In this section we will focus on the habitat units assigned in the field: their diversity, some indicators of habitat heterogeneity/quality, and how they relate to our residual pool determinations.

We have intentionally kept the habitat unit section distinct from other metrics. This is because assigning habitat units in the field requires expertise and judgement, with a greater degree of subjectivity than the other data collected. Because the nature of restoration monitoring often spans many years, it is unlikely that all measurements at one site would be conducted by the same person, even if that same person were capable of perfect consistency. As such, interpretation of field-assigned habitat unit data should be undertaken with a larger degree of caution, and with reference to field notes and photos where available.

Having said that, most people interested in streams are perfectly capable of identifying pools from riffles, presence of debris jams, etc. In the field people are able to integrate a variety of information (water velocity, roughness, depth, sound, taste, etc.) to assign habitats. In contrast, our residual pool code makes objective inferences based only on water depths and slope. As such, you may observe differences in the habitat unit and residual pool assignments (e.g., where a field-assigned riffle is present within a code-assigned residual pool). Hopefully, any such differences are relatively minor and, regardless, this should not effect our ability to track change over time (or compare similar habitats) within each approach.

First we will import the dataframe containing the residual pool information, which we exported to your output folder from the Residual Pool script.

In the field you may have recorded primary and secondary habitat units. We will focus only on primary habitat units at this point. The habitat codes that you recorded in the field will be used in the analysis, but we recognise that there may also be habitat types that fall outside of the habitat classification system applied in the field protocol. For example, when channels are artificially created, modified, or heavily degraded by invasive vegetation / altered flow / sediment regimes etc., some areas of slow-water habitat may not resemble natural scoured/dammed pools. If you have encountered cases of slow water that you could not comfortably classify, we will introduce the code ‘SLOW’ to represent these conditions, and we will consider this a type of ‘dammed pool’ for the sake of analyses.

As a reminder, the habitat codes we assigned in the field were:

Habitat Unit Codes:
Category Habitat Unit Codes
Fast water Falls = F
Cascade = CA
Rapids = RAP
Riffle = RIF
Chute = CH
Sheet = SH
Run = RUN
Scour Pools Eddy = ED
Trench = TR
Mid-channel = MID
Convergence = CON
Lateral = LAT
Plunge = PL
Dammed Pools Debris dam = DEB
Beaver dam = BEA
Landslide = LAN
Backwater = BAC
Abandoned Channel = AB

Habitat Unit Visualisation

It can be useful to take a look at the distribution of habitat units in your reach, and how these correspond to the thalweg depth and residual surface estimate. We generate some plots that align these data, and export them as html to your output folder.

Certain features of the above figure may be of particular interest. For example, if your reach contained DEB (debris dammed pools) or BEA (beaver dammed pools), you can see how these features correspond to the residual pools (pools where flow approaches zero) in your reach. We can ask what proportion of reach residual pool habitat, based on habitat unit assignments, is comprised of beaver or debris dammed pools. This may be of particular interest where process-based restoration work has been initiated.

For this question, we consider any residual pool that is 50% or more assigned as BEA or DEB as being a beaver or debris pool in its entirety. Similarly, if the field assignment of BEA or DEB corresponds with a residual pool outlet (i.e., debris or a beaver dam was observed holding back water) then the entire residual pool will be assigned as a beaver/debris dam pool, even if the full extent was not recognised as such in the field. This approach is to account for differences between code-assigned residual pools and pools as recognised in the field, such as where a sequence of beaver pool, debris pool, scour pool is observed, but in fact the whole section appears to be controlled/backwatered by the downstream beaver dam, based on the residual surface.

Below we display and export summary data for each year at each reach, and the individual pool data with their status as beaver/debris dam. With our Hatchery Channel example data there is one debris dam residual pool identified in 2024 but none in 2025. With reference to the above figure, this is explained by the woody debris being at the location of a pool outlet in 2024, but the same magnitude of debris is located mid-pool in 2025 and is therefore considered not to be functionally creating the pool.

Beaver or Debris Pools Summary All Sites Years
site_year total_length total_sagittal_area beaver_length_prop debris_length_prop beaver_sagittal_area_prop debris_sagittal_area_prop
Brousseau Channel.2024 127 12.747 0 0.000 0 0.000
Hatchery Channel.2024 132 26.539 0 0.098 0 0.171
Brousseau Channel.2025 141 69.802 0 0.000 0 0.000
Hatchery Channel.2025 139 85.556 0 0.000 0 0.000
Beaver or Debris Pools Brousseau Channel 2024
pool_id pool_length sagittal_area pool_type
1 21 2.944 Other
2 1 0.058 Other
3 22 2.240 Other
4 1 0.008 Other
5 1 0.008 Other
6 9 1.080 Other
7 5 0.775 Other
8 9 0.990 Other
9 3 0.205 Other
10 23 2.224 Other
11 2 0.068 Other
12 3 0.345 Other
13 3 0.023 Other
14 13 0.897 Other
15 4 0.056 Other
16 7 0.829 Other
Beaver or Debris Pools Hatchery Channel 2024
pool_id pool_length sagittal_area pool_type
1 24 7.674 Other
2 14 2.643 Other
3 11 1.578 Other
4 6 0.823 Other
5 31 4.151 Other
6 12 1.968 Other
7 13 4.539 Debris-Dam Pool
8 9 1.290 Other
9 10 1.855 Other
10 2 0.018 Other
Beaver or Debris Pools Brousseau Channel 2025
pool_id pool_length sagittal_area pool_type
1 60 31.973 Other
2 18 7.951 Other
3 33 15.334 Other
4 30 14.543 Other
Beaver or Debris Pools Hatchery Channel 2025
pool_id pool_length sagittal_area pool_type
1 38 31.648 Other
2 19 9.484 Other
3 1 0.437 Other
4 57 31.186 Other
5 24 12.801 Other

A summary figure is also generated and exported to your output folder. The composite figure displays the reachwide proportion of residual pool length/sagittal area that is comprised of beaver and debris dammed pools, for each reach across time.

Habitat Unit Diversity

Now let’s take a look at diversity metrics for the habitat units assigned in the field. When we refer to pools here, we are referring only to habitat assigned in the field, and not the residual pools that we identified in our previous script. Remember that while residual pools are an estimate of habitat when flow approaches zero, the pools assigned in the field represent habitat as observable at that particular flow condition.

Before reading into the below metrics, it is worth considering that people classifying Habitat Units may vary in experience and/or confidence, and could (for example) ‘default’ to a particular type of pool that they are most familiar when they are unsure. This could mean that identical habitats can differ in certain metrics based on the observer. We feel that pool percent and pool-to-riffle ratio are robust to these concerns, that scoured and dammed pool percentages are fairly robust in the majority of cases, but that the Shannon diversity index is prone to underestimates of diversity if observers are not confident assigning any of the appropriate habitat unit categories. As such, exercise extra caution with interpreting changes in Shannon indices where observers have changed over time or between reaches (or even if significant time has passed for the same observer).

Habitat Unit Diversity Metrics
Site year shannon_diversity_index pool_percent scourpool_percent dammedpool_percent pool_to_riffle_ratio
Brousseau Channel 2024 0.823 63.194 0 63.194 10.111
Brousseau Channel 2025 0.828 63.194 0 63.194 10.111
Hatchery Channel 2024 0.204 96.853 0 96.853 0.000
Hatchery Channel 2025 0.228 97.552 0 97.552 0.000

LS0tDQp0aXRsZTogIkxvbmdpdHVkaW5hbCBTdXJ2ZXkgNSBIYWJpdGF0IFVuaXRzIg0KYXV0aG9yOiAiT2xpdmVyIEZyYW5rbGluICYgTmljY2kgWmFyZ2FycG91ciINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD05LCBlY2hvID0gVFJVRSkNCmlmICghcmVxdWlyZU5hbWVzcGFjZSgicGFjbWFuIiwgcXVpZXRseSA9IFRSVUUpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpfQ0KcGFjbWFuOjpwX2xvYWQoZ2Vvc3BoZXJlLCBEVCwgdGlkeXZlcnNlLCBkcGx5ciwgdGlkeXIsZ2dwbG90Mixrbml0cixncmlkRXh0cmEsa2FibGVFeHRyYSwgcGxvdGx5LGNvd3Bsb3QsUkNvbG9yQnJld2VyLGh0bWx3aWRnZXRzLCAgdXBkYXRlPUYpDQpgYGANCg0KYGBge3IgZXhwb3J0IGZ1bmN0aW9ucyBhbmQgZm9sZGVyLCBlY2hvID0gRkFMU0V9DQojIGZ1bmN0aW9ucyB0byB1c2UgZm9yIGV4cG9ydGluZyByZXN1bHRzIHRvIG91dHB1dF9mb2xkZXIgKHdoaWNoIGlzIHByb21wdGVkIGluIFIgd2hlbiBub3QgaW4gUiBlbnZpcm9ubWVudCkNCg0KI2V4cG9ydCBmaWd1cmUgKHBkZiBmb3Igc3RhdGljIGdncGxvdCBwbG90cywgaHRtbCBmb3IgaW50ZXJhY3RpdmUgcGxvdGx5IHBsb3RzKQ0KZXhwb3J0X3Bsb3QgPC0gZnVuY3Rpb24ocGxvdCwgZmlsZW5hbWUpIHsNCiAgaWYgKGluaGVyaXRzKHBsb3QsICJnZ3Bsb3QiKSkgew0KICAgICMgRXhwb3J0IGdncGxvdCBhcyBQREYNCiAgICBnZ3NhdmUoDQogICAgICBmaWxlbmFtZSA9IGZpbGUucGF0aChvdXRwdXRfZm9sZGVyLCBmaWxlbmFtZSksDQogICAgICBwbG90ID0gcGxvdCwNCiAgICAgIGRldmljZSA9ICJwZGYiLA0KICAgICAgd2lkdGggPSAxMSwNCiAgICAgIGhlaWdodCA9IDguNQ0KICAgICkNCiAgfSBlbHNlIGlmIChpbmhlcml0cyhwbG90LCAicGxvdGx5IikpIHsNCiAgICAjIEVuc3VyZSB0aGUgZmlsZW5hbWUgaGFzIC5odG1sIGV4dGVuc2lvbg0KICAgIGh0bWxfZmlsZW5hbWUgPC0gZmlsZS5wYXRoKG91dHB1dF9mb2xkZXIsIHN1YigiXFwucGRmJCIsICIuaHRtbCIsIGZpbGVuYW1lKSkNCiAgICAjIEV4cG9ydCBwbG90bHkgYXMgYSAqKnNpbmdsZSBzZWxmLWNvbnRhaW5lZCoqIEhUTUwgZmlsZQ0KICAgIHNhdmVXaWRnZXQoDQogICAgICB3aWRnZXQgPSBwbG90LCANCiAgICAgIGZpbGUgPSBodG1sX2ZpbGVuYW1lLCANCiAgICAgIHNlbGZjb250YWluZWQgPSBUUlVFICAjIA0KICAgICkNCiAgfSBlbHNlIHsNCiAgICBzdG9wKCJVbnN1cHBvcnRlZCBwbG90IHR5cGUuIE9ubHkgZ2dwbG90IGFuZCBwbG90bHkgb2JqZWN0cyBhcmUgc3VwcG9ydGVkLiIpDQogIH0NCn0NCg0KIyBGdW5jdGlvbiB0byBzYXZlIGEgdGFibGUNCmV4cG9ydF90YWJsZSA8LSBmdW5jdGlvbih0YWJsZSwgZmlsZW5hbWUpIHsNCiAgd3JpdGUuY3N2KA0KICAgIHRhYmxlLA0KICAgIGZpbGUgPSBmaWxlLnBhdGgob3V0cHV0X2ZvbGRlciwgZmlsZW5hbWUpLA0KICAgIHJvdy5uYW1lcyA9IEZBTFNFDQogICkNCn0NCg0KIyBGdW5jdGlvbiB0byBzYXZlIHN1bW1hcnkgYXMgdHh0DQpleHBvcnRfc3VtbWFyeSA8LSBmdW5jdGlvbihzdW1tYXJ5X3RleHQsIGZpbGVuYW1lX2Jhc2UpIHsNCiAgIyBFbnN1cmUgc3VtbWFyeV90ZXh0IGlzIGEgY2hhcmFjdGVyIHZlY3RvciAoaXQgc2hvdWxkIGFscmVhZHkgYmUsIGJ1dCBqdXN0IGluIGNhc2UpDQogIHN1bW1hcnlfdGV4dCA8LSBhcy5jaGFyYWN0ZXIoc3VtbWFyeV90ZXh0KQ0KICAgICMgU2F2ZSBhcyAudHh0DQogIHR4dF9wYXRoIDwtIGZpbGUucGF0aChvdXRwdXRfZm9sZGVyLCBwYXN0ZTAoZmlsZW5hbWVfYmFzZSwgIi50eHQiKSkNCiAgd3JpdGVMaW5lcyhzdW1tYXJ5X3RleHQsIGNvbiA9IHR4dF9wYXRoKQ0KfQ0KDQojIEV4YW1wbGVzIG9mIGV4cG9ydGluZyBpbmRpdmlkdWFsIHJlc3VsdHM6DQojIEV4cG9ydCBhIGZpZ3VyZQ0KIyBleHBvcnRfcGxvdChnZ3Bsb3RfcGxvdCwgIlRoYWx3ZWcgV2F0ZXIgRGVwdGggYnkgRGlzdGFuY2UgVXBzdHJlYW0ucGRmIikNCiMgZXhwb3J0X3Bsb3QocGxvdGx5X3Bsb3QsICJUaGFsd2VnIFdhdGVyIERlcHRoIGJ5IERpc3RhbmNlIFVwc3RyZWFtLmh0bWwiKQ0KIyANCiMgIyBFeHBvcnRpbmcgYSB0YWJsZQ0KIyBzdW1tYXJ5X3RhYmxlIDwtIHN1bW1hcnkobXRjYXJzKQ0KIyBleHBvcnRfdGFibGUoYXMuZGF0YS5mcmFtZShzdW1tYXJ5X3RhYmxlKSwgInN1bW1hcnlfdGFibGUuY3N2IikNCiMgDQojIEV4YW1wbGUgb2YgZXhwb3J0aW5nIGEgc3VtbWFyeQ0KIyBzdW1tYXJ5X3RleHQgPC0gY2FwdHVyZS5vdXRwdXQoc3VtbWFyeShtdGNhcnMpKQ0KIyBleHBvcnRfc3VtbWFyeShzdW1tYXJ5X3RleHQsICJzdW1tYXJ5IikNCg0KIyBiZWxvdyBjb2RlIHRvIGNvbmZpcm0gYW4gb3V0cHV0IGZvbGRlciBpcyBhbHJlYWR5IHNwZWNpZmllZCwgT1Igd2lsbCByZXF1ZXN0IGl0IGlzIHNwZWNpZmllZCBpbiBSIChpbnRlcmFjdGl2ZWx5IHZpYSByZWFkbGluZSkNCiMgYXV0aG9ycyBvdXRwdXQgZm9sZGVyOiAifi9HaXQvQ29yZSBNb25pdG9yaW5nL3N0YW5kYXJkaXNlZCBwcm90b2NvbHMvZGF0YV90aWRpZXIvTG9uZ2l0dWRpbmFsIg0KIyBCVVQgaWYgeW91IHdhbnQgdG8ga25pdCwgeW91IHdpbGwgbmVlZCB0byBzcGVjaWZ5IGEgZGVmYXVsdCBsb2NhdGlvbiAod2l0aGluIHRoZSAnZWxzZScgdGVybSkNCmlmIChpbnRlcmFjdGl2ZSgpKSB7DQogIHdoaWxlICghZXhpc3RzKCJvdXRwdXRfZm9sZGVyIikgfHwgIWRpci5leGlzdHMob3V0cHV0X2ZvbGRlcikpIHsNCiAgICBvdXRwdXRfZm9sZGVyIDwtIHJlYWRsaW5lKHByb21wdCA9ICJTcGVjaWZ5IHRoZSBvdXRwdXQgZm9sZGVyOiAiKQ0KICAgIGlmICghZGlyLmV4aXN0cyhvdXRwdXRfZm9sZGVyKSkgew0KICAgICAgdHJ5Q2F0Y2goew0KICAgICAgICBkaXIuY3JlYXRlKG91dHB1dF9mb2xkZXIsIHJlY3Vyc2l2ZSA9IFRSVUUpDQogICAgICAgIG1lc3NhZ2UoIkNyZWF0ZWQgZm9sZGVyOiAiLCBvdXRwdXRfZm9sZGVyKQ0KICAgICAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7DQogICAgICAgIG1lc3NhZ2UoIkludmFsaWQgZm9sZGVyLiBQbGVhc2UgdHJ5IGFnYWluLiIpDQogICAgICAgIG91dHB1dF9mb2xkZXIgPC0gTlVMTA0KICAgICAgfSkNCiAgICB9DQogIH0NCn0gZWxzZSB7DQogICMgU3BlY2lmeSBhIGRlZmF1bHQgZm9sZGVyIGZvciBub24taW50ZXJhY3RpdmUgbW9kZSAoZS5nLiwga25pdHRpbmcpDQogIG91dHB1dF9mb2xkZXIgPC0gIn4vR2l0L0NvcmUgTW9uaXRvcmluZy9zdGFuZGFyZGlzZWQgcHJvdG9jb2xzL2RhdGFfdGlkaWVyL0xvbmdpdHVkaW5hbCINCiAgaWYgKCFkaXIuZXhpc3RzKG91dHB1dF9mb2xkZXIpKSB7DQogICAgZGlyLmNyZWF0ZShvdXRwdXRfZm9sZGVyLCByZWN1cnNpdmUgPSBUUlVFKQ0KICAgIG1lc3NhZ2UoIkRlZmF1bHQgb3V0cHV0IGZvbGRlciBjcmVhdGVkOiAiLCBvdXRwdXRfZm9sZGVyKQ0KICB9DQp9DQpgYGANCg0KSW4gdGhpcyBzZWN0aW9uIHdlIHdpbGwgZm9jdXMgb24gdGhlIGhhYml0YXQgdW5pdHMgYXNzaWduZWQgaW4gdGhlIGZpZWxkOiB0aGVpciBkaXZlcnNpdHksIHNvbWUgaW5kaWNhdG9ycyBvZiBoYWJpdGF0IGhldGVyb2dlbmVpdHkvcXVhbGl0eSwgYW5kIGhvdyB0aGV5IHJlbGF0ZSB0byBvdXIgcmVzaWR1YWwgcG9vbCBkZXRlcm1pbmF0aW9ucy4NCiANCldlIGhhdmUgaW50ZW50aW9uYWxseSBrZXB0IHRoZSBoYWJpdGF0IHVuaXQgc2VjdGlvbiBkaXN0aW5jdCBmcm9tIG90aGVyIG1ldHJpY3MuIFRoaXMgaXMgYmVjYXVzZSBhc3NpZ25pbmcgaGFiaXRhdCB1bml0cyBpbiB0aGUgZmllbGQgcmVxdWlyZXMgZXhwZXJ0aXNlIGFuZCBqdWRnZW1lbnQsIHdpdGggYSBncmVhdGVyIGRlZ3JlZSBvZiBzdWJqZWN0aXZpdHkgdGhhbiB0aGUgb3RoZXIgZGF0YSBjb2xsZWN0ZWQuIEJlY2F1c2UgdGhlIG5hdHVyZSBvZiByZXN0b3JhdGlvbiBtb25pdG9yaW5nIG9mdGVuIHNwYW5zIG1hbnkgeWVhcnMsIGl0IGlzIHVubGlrZWx5IHRoYXQgYWxsIG1lYXN1cmVtZW50cyBhdCBvbmUgc2l0ZSB3b3VsZCBiZSBjb25kdWN0ZWQgYnkgdGhlIHNhbWUgcGVyc29uLCBldmVuIGlmIHRoYXQgc2FtZSBwZXJzb24gd2VyZSBjYXBhYmxlIG9mIHBlcmZlY3QgY29uc2lzdGVuY3kuIEFzIHN1Y2gsIGludGVycHJldGF0aW9uIG9mIGZpZWxkLWFzc2lnbmVkIGhhYml0YXQgdW5pdCBkYXRhIHNob3VsZCBiZSB1bmRlcnRha2VuIHdpdGggYSBsYXJnZXIgZGVncmVlIG9mIGNhdXRpb24sIGFuZCB3aXRoIHJlZmVyZW5jZSB0byBmaWVsZCBub3RlcyBhbmQgcGhvdG9zIHdoZXJlIGF2YWlsYWJsZS4gDQoNCkhhdmluZyBzYWlkIHRoYXQsIG1vc3QgcGVvcGxlIGludGVyZXN0ZWQgaW4gc3RyZWFtcyBhcmUgcGVyZmVjdGx5IGNhcGFibGUgb2YgaWRlbnRpZnlpbmcgcG9vbHMgZnJvbSByaWZmbGVzLCBwcmVzZW5jZSBvZiBkZWJyaXMgamFtcywgZXRjLiBJbiB0aGUgZmllbGQgcGVvcGxlIGFyZSBhYmxlIHRvIGludGVncmF0ZSBhIHZhcmlldHkgb2YgaW5mb3JtYXRpb24gKHdhdGVyIHZlbG9jaXR5LCByb3VnaG5lc3MsIGRlcHRoLCBzb3VuZCwgdGFzdGUsIGV0Yy4pIHRvIGFzc2lnbiBoYWJpdGF0cy4gSW4gY29udHJhc3QsIG91ciByZXNpZHVhbCBwb29sIGNvZGUgbWFrZXMgb2JqZWN0aXZlIGluZmVyZW5jZXMgYmFzZWQgb25seSBvbiB3YXRlciBkZXB0aHMgYW5kIHNsb3BlLiBBcyBzdWNoLCB5b3UgbWF5IG9ic2VydmUgZGlmZmVyZW5jZXMgaW4gdGhlIGhhYml0YXQgdW5pdCBhbmQgcmVzaWR1YWwgcG9vbCBhc3NpZ25tZW50cyAoZS5nLiwgd2hlcmUgYSBmaWVsZC1hc3NpZ25lZCByaWZmbGUgaXMgcHJlc2VudCB3aXRoaW4gYSBjb2RlLWFzc2lnbmVkIHJlc2lkdWFsIHBvb2wpLiBIb3BlZnVsbHksIGFueSBzdWNoIGRpZmZlcmVuY2VzIGFyZSByZWxhdGl2ZWx5IG1pbm9yIGFuZCwgcmVnYXJkbGVzcywgdGhpcyBzaG91bGQgbm90IGVmZmVjdCBvdXIgYWJpbGl0eSB0byB0cmFjayBjaGFuZ2Ugb3ZlciB0aW1lIChvciBjb21wYXJlIHNpbWlsYXIgaGFiaXRhdHMpIHdpdGhpbiBlYWNoIGFwcHJvYWNoLiANCg0KRmlyc3Qgd2Ugd2lsbCBpbXBvcnQgdGhlIGRhdGFmcmFtZSBjb250YWluaW5nIHRoZSByZXNpZHVhbCBwb29sIGluZm9ybWF0aW9uLCB3aGljaCB3ZSBleHBvcnRlZCB0byB5b3VyIG91dHB1dCBmb2xkZXIgZnJvbSB0aGUgUmVzaWR1YWwgUG9vbCBzY3JpcHQuDQoNCmBgYHtyIGltcG9ydCBkYXRhLCBlY2hvPUZBTFNFfQ0KaW1wb3J0ZWRkYXRhIDwtIGZpbGUucGF0aChvdXRwdXRfZm9sZGVyLCAiUmVzaWR1YWxzX2RhdGFmcmFtZS5jc3YiKQ0KcmVzaWR1YWxzLmRmIDwtIHJlYWQuY3N2KGltcG9ydGVkZGF0YSkgIA0KDQojIyBpZiB5b3UgbmVlZCB0byBzcGVjaWZ5IGEgZGlmZmVyZW50IGxvY2F0aW9uIHRvIGltcG9ydCBmcm9tLCB1c2UgYmVsb3cgY29kZToNCiMgaW1wb3J0ZWRkYXRhPC1yZWFkLmNzdigifi9HaXQvQ29yZSBNb25pdG9yaW5nL3N0YW5kYXJkaXNlZCBwcm90b2NvbHMvZGF0YV90aWRpZXIvTG9uZ2l0dWRpbmFsL1Jlc2lkdWFsc19kYXRhZnJhbWUuY3N2IikgIyBzcGVjaWZ5IHlvdXIgZmlsZSBsb2NhdGlvbiAmIG5hbWUgaGVyZQ0KIyByZXNpZHVhbHMuZGY8LWRhdGEuZnJhbWUoaW1wb3J0ZWRkYXRhKQ0KYGBgDQpJbiB0aGUgZmllbGQgeW91IG1heSBoYXZlIHJlY29yZGVkIHByaW1hcnkgYW5kIHNlY29uZGFyeSBoYWJpdGF0IHVuaXRzLiBXZSB3aWxsIGZvY3VzIG9ubHkgb24gcHJpbWFyeSBoYWJpdGF0IHVuaXRzIGF0IHRoaXMgcG9pbnQuIFRoZSBoYWJpdGF0IGNvZGVzIHRoYXQgeW91IHJlY29yZGVkIGluIHRoZSBmaWVsZCB3aWxsIGJlIHVzZWQgaW4gdGhlIGFuYWx5c2lzLCBidXQgd2UgcmVjb2duaXNlIHRoYXQgdGhlcmUgbWF5IGFsc28gYmUgaGFiaXRhdCB0eXBlcyB0aGF0IGZhbGwgb3V0c2lkZSBvZiB0aGUgaGFiaXRhdCBjbGFzc2lmaWNhdGlvbiBzeXN0ZW0gYXBwbGllZCBpbiB0aGUgZmllbGQgcHJvdG9jb2wuIEZvciBleGFtcGxlLCB3aGVuIGNoYW5uZWxzIGFyZSBhcnRpZmljaWFsbHkgY3JlYXRlZCwgbW9kaWZpZWQsIG9yIGhlYXZpbHkgZGVncmFkZWQgYnkgaW52YXNpdmUgdmVnZXRhdGlvbiAvIGFsdGVyZWQgZmxvdyAvIHNlZGltZW50IHJlZ2ltZXMgZXRjLiwgc29tZSBhcmVhcyBvZiBzbG93LXdhdGVyIGhhYml0YXQgbWF5IG5vdCByZXNlbWJsZSBuYXR1cmFsIHNjb3VyZWQvZGFtbWVkIHBvb2xzLiBJZiB5b3UgaGF2ZSBlbmNvdW50ZXJlZCBjYXNlcyBvZiBzbG93IHdhdGVyIHRoYXQgeW91IGNvdWxkIG5vdCBjb21mb3J0YWJseSBjbGFzc2lmeSwgd2Ugd2lsbCBpbnRyb2R1Y2UgdGhlIGNvZGUgJ1NMT1cnIHRvIHJlcHJlc2VudCB0aGVzZSBjb25kaXRpb25zLCBhbmQgd2Ugd2lsbCBjb25zaWRlciB0aGlzIGEgdHlwZSBvZiAnZGFtbWVkIHBvb2wnIGZvciB0aGUgc2FrZSBvZiBhbmFseXNlcy4NCg0KQXMgYSByZW1pbmRlciwgdGhlIGhhYml0YXQgY29kZXMgd2UgYXNzaWduZWQgaW4gdGhlIGZpZWxkIHdlcmU6DQoNCiMjIyMjIEhhYml0YXQgVW5pdCBDb2RlczoNCg0KfCBDYXRlZ29yeSB8IEhhYml0YXQgVW5pdCBDb2RlcyB8DQp8IDotLS06IHwgOi0tLSB8DQp8IEZhc3Qgd2F0ZXIgfCBGYWxscyA9IEYgPGJyPkNhc2NhZGUgPSBDQTxicj5SYXBpZHMgPSBSQVA8YnI+UmlmZmxlID0gUklGPGJyPkNodXRlID0gQ0g8YnI+U2hlZXQgPSBTSDxicj5SdW4gPSBSVU4gfA0KfCBTY291ciBQb29scyB8IEVkZHkgPSBFRDxicj5UcmVuY2ggPSBUUjxicj5NaWQtY2hhbm5lbCA9IE1JRDxicj5Db252ZXJnZW5jZSA9IENPTjxicj5MYXRlcmFsID0gTEFUPGJyPlBsdW5nZSA9IFBMIHwNCnwgRGFtbWVkIFBvb2xzIHwgRGVicmlzIGRhbSA9IERFQjxicj5CZWF2ZXIgZGFtID0gQkVBPGJyPkxhbmRzbGlkZSA9IExBTjxicj5CYWNrd2F0ZXIgPSBCQUM8YnI+QWJhbmRvbmVkIENoYW5uZWwgPSBBQiB8DQoNCmBgYHtyIGhhYml0YXQgY29kZSBhbGlnbm1lbnQsIGVjaG8gPSBGQUxTRX0NCiN0aGlzIGNvZGUgYXR0ZW1wdHMgdG8gY29ycmVjdC9hbGlnbiB0aGUgY29kZXMgd2l0aCB0aG9zZSBsaXN0ZWQgYWJvdmUuIFRoZXJlIGlzIGxvdHMgb2YgcG90ZW50aWFsIGZvciBjaGFyYWN0ZXIgc3RyaW5ncyB3ZSBkaWQgbm90IHByZWRpY3QNCnJlc2lkdWFscy5kZiA8LSByZXNpZHVhbHMuZGYgJT4lDQogIG11dGF0ZShIVV9QcmltYXJ5ID0gY2FzZV93aGVuKA0KICAgIGdyZXBsKCJmYWxscyIsIEhVX1ByaW1hcnksIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiRiIsDQogICAgZ3JlcGwoImNhc2MuKiIsIEhVX1ByaW1hcnksIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiQ0EiLA0KICAgIGdyZXBsKCJyYXBpZC4qIiwgSFVfUHJpbWFyeSwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJSQVAiLA0KICAgIGdyZXBsKCJyaWZmLioiLCBIVV9QcmltYXJ5LCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIlJJRiIsDQogICAgZ3JlcGwoImNodXRlIiwgSFVfUHJpbWFyeSwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJDSCIsDQogICAgZ3JlcGwoInNoZWV0IiwgSFVfUHJpbWFyeSwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJTSCIsDQogICAgZ3JlcGwoInJ1biIsIEhVX1ByaW1hcnksIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiUlVOIiwNCiAgICBncmVwbCgiZWRkeSIsIEhVX1ByaW1hcnksIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiRUQiLA0KICAgIGdyZXBsKCJ0cmVuY2giLCBIVV9QcmltYXJ5LCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIlRSIiwNCiAgICBncmVwbCgibWlkLj9jaGFubmVsIiwgSFVfUHJpbWFyeSwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJNSUQiLA0KICAgIGdyZXBsKCJjb252LioiLCBIVV9QcmltYXJ5LCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkNPTiIsDQogICAgZ3JlcGwoImxhdGVyYWwiLCBIVV9QcmltYXJ5LCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkxBVCIsDQogICAgZ3JlcGwoInBsdW5nZSIsIEhVX1ByaW1hcnksIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiUEwiLA0KICAgIGdyZXBsKCJkZWIuKiIsIEhVX1ByaW1hcnksIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiREVCIiwNCiAgICBncmVwbCgiYmVhdi4qIiwgSFVfUHJpbWFyeSwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJCRUEiLA0KICAgIGdyZXBsKCIuKnNsaWRlIiwgSFVfUHJpbWFyeSwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJMQU4iLA0KICAgIGdyZXBsKCJiYWNrLioiLCBIVV9QcmltYXJ5LCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkJBQyIsDQogICAgZ3JlcGwoImFiYW5kLioiLCBIVV9QcmltYXJ5LCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkFCIiwNCiAgICBncmVwbCgicG9vbCIsIEhVX1ByaW1hcnksIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiU0xPVyIsDQogICAgVFJVRSB+IEhVX1ByaW1hcnkgICMgS2VlcCBvcmlnaW5hbCBpZiBubyBtYXRjaA0KICApDQopDQpgYGANCg0KIyBIYWJpdGF0IFVuaXQgVmlzdWFsaXNhdGlvbg0KDQpJdCBjYW4gYmUgdXNlZnVsIHRvIHRha2UgYSBsb29rIGF0IHRoZSBkaXN0cmlidXRpb24gb2YgaGFiaXRhdCB1bml0cyBpbiB5b3VyIHJlYWNoLCBhbmQgaG93IHRoZXNlIGNvcnJlc3BvbmQgdG8gdGhlIHRoYWx3ZWcgZGVwdGggYW5kIHJlc2lkdWFsIHN1cmZhY2UgZXN0aW1hdGUuIFdlIGdlbmVyYXRlIHNvbWUgcGxvdHMgdGhhdCBhbGlnbiB0aGVzZSBkYXRhLCBhbmQgZXhwb3J0IHRoZW0gYXMgaHRtbCB0byB5b3VyIG91dHB1dCBmb2xkZXIuDQoNCmBgYHtyIHBsb3QgaGFiaXRhdCB1bml0cyBsb25nLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9MTAsIGVjaG89RkFMU0V9DQojIyB0aGVyZSBhcmUgYSBmZXcgZm9ybWF0dGluZyBpc3N1ZXMgaGVyZSwgd2hpY2ggd2UgaG9wZSB0byBmaXggKHJlcGV0aXRpdmUgbGVnZW5kLCBvdmVybGFwcGluZyB0aXRsZSB0ZXh0LCBhYnNlbnQgbGFibGVzKQ0KIyBHZW5lcmF0ZSBjb2xvciBtYXAgZm9yIGhhYml0YXQgdW5pdHMNCnVuaXF1ZV9oYWJpdGF0X3VuaXRzIDwtIHVuaXF1ZShyZXNpZHVhbHMuZGYkSFVfUHJpbWFyeSkNCmhhYml0YXRfY29sb3JzIDwtIGMoDQogICIjRTY5RjAwIiwgIiM1NkI0RTkiLCAiIzAwOUU3MyIsICIjNkEwNTcyIiwgIiMyNjQ2NTMiLCAiI0Q1NUUwMCIsICIjQ0M3OUE3IiwgIiM5OTk5OTkiLA0KICAiI0Y0QTI2MSIsICIjMDA3MkIyIiwgIiMyQTlEOEYiLCAiI0U3NkY1MSIsICIjOEFCMTdEIiwgIiNEREExNUUiLCAiI0I1ODM4RCIsICIjRjBFNDQyIiwNCiAgIiMwMDNGNUMiLCAiI0JDNTA5MCINCikNCmhhYml0YXRfY29sb3JfbWFwIDwtIHNldE5hbWVzKGhhYml0YXRfY29sb3JzLCB1bmlxdWVfaGFiaXRhdF91bml0cykNCg0KIyBDYWxjdWxhdGUgYmFyIHBvc2l0aW9ucyBhbmQgd2lkdGhzIGZvciBIVSBkYXRhDQpyZXNpZHVhbHMuZGYgPC0gcmVzaWR1YWxzLmRmICU+JQ0KICBhcnJhbmdlKFNpdGUsIHllYXIsIGRpc3RhbmNlKSAlPiUNCiAgZ3JvdXBfYnkoU2l0ZSwgeWVhcikgJT4lDQogIG11dGF0ZSgNCiAgICBiYXJfc3RhcnQgPSBkaXN0YW5jZSAtIChkaXN0YW5jZSAtIGxhZyhkaXN0YW5jZSwgZGVmYXVsdCA9IGZpcnN0KGRpc3RhbmNlKSkpIC8gMiwNCiAgICBiYXJfZW5kID0gZGlzdGFuY2UgKyAobGVhZChkaXN0YW5jZSwgZGVmYXVsdCA9IGxhc3QoZGlzdGFuY2UpKSAtIGRpc3RhbmNlKSAvIDIsDQogICAgYmFyX3dpZHRoID0gYmFyX2VuZCAtIGJhcl9zdGFydA0KICApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIGZpbHRlcighaXMubmEoYmFyX3N0YXJ0KSAmICFpcy5uYShiYXJfZW5kKSkNCg0KIyBDcmVhdGUgbGlzdCBmb3IgaW5kaXZpZHVhbCBwbG90cw0KcGxvdHMgPC0gbGlzdCgpDQoNCiMgTG9vcCB0aHJvdWdoIGVhY2ggdW5pcXVlIFNpdGUgYW5kIFllYXIgY29tYmluYXRpb24NCmZvciAoc2l0ZV95ZWFyIGluIHVuaXF1ZShwYXN0ZShyZXNpZHVhbHMuZGYkU2l0ZSwgcmVzaWR1YWxzLmRmJHllYXIpKSkgew0KICBzaXRlX3llYXJfZGF0YSA8LSByZXNpZHVhbHMuZGYgJT4lIA0KICAgIGZpbHRlcihwYXN0ZShTaXRlLCB5ZWFyKSA9PSBzaXRlX3llYXIpICU+JQ0KICAgIGZpbHRlcihkaXN0YW5jZSA+PSAwKSAgIyBGaWx0ZXIgb3V0IG5lZ2F0aXZlIGRpc3RhbmNlIHZhbHVlcyAoYXJ0aWZpY2lhbCBuaWNrcG9pbnRzKQ0KICANCiAgcGxvdCA8LSBwbG90X2x5KCkNCiAgDQogICMgQWRkIEhhYml0YXQgVW5pdCBiYXJzIGF0IHZlcnkgdG9wDQogIGZvciAoaHUgaW4gdW5pcXVlKHNpdGVfeWVhcl9kYXRhJEhVX1ByaW1hcnkpKSB7DQogICAgaHVfZGF0YSA8LSBzaXRlX3llYXJfZGF0YSAlPiUgZmlsdGVyKEhVX1ByaW1hcnkgPT0gaHUpDQogICAgDQogICAgcGxvdCA8LSBwbG90ICU+JQ0KICAgICAgYWRkX3NlZ21lbnRzKA0KICAgICAgICBkYXRhID0gaHVfZGF0YSwNCiAgICAgICAgeCA9IH5iYXJfc3RhcnQsDQogICAgICAgIHhlbmQgPSB+YmFyX2VuZCwNCiAgICAgICAgeSA9IDAuMDEsDQogICAgICAgIHllbmQgPSAwLjAxLA0KICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9IGhhYml0YXRfY29sb3JfbWFwW2h1XSwgd2lkdGggPSAyMCksDQogICAgICAgIG5hbWUgPSBodQ0KICAgICAgKQ0KICB9DQogIA0KICAjIFRoZW4gYWRkIFRoYWx3ZWcgRGVwdGgsIHJlcyBzdXJmYWNlDQogIHBsb3QgPC0gcGxvdCAlPiUNCiAgICBhZGRfdHJhY2UoDQogICAgICBkYXRhID0gc2l0ZV95ZWFyX2RhdGEsDQogICAgICB4ID0gfmRpc3RhbmNlLA0KICAgICAgeSA9IH4tVGhhbHdlZ19EZXB0aF9tLA0KICAgICAgdHlwZSA9ICJzY2F0dGVyIiwNCiAgICAgIG1vZGUgPSAibGluZXMiLA0KICAgICAgbGluZSA9IGxpc3Qod2lkdGggPSAyLCBjb2xvciA9ICJibGFjayIpLA0KICAgICAgbmFtZSA9ICJUaGFsd2VnIERlcHRoIg0KICAgICkgJT4lDQogICAgYWRkX3RyYWNlKA0KICAgICAgZGF0YSA9IHNpdGVfeWVhcl9kYXRhLA0KICAgICAgeCA9IH5kaXN0YW5jZSwNCiAgICAgIHkgPSB+LXJlc2lkdWFsX3N1cmZhY2UsDQogICAgICB0eXBlID0gInNjYXR0ZXIiLA0KICAgICAgbW9kZSA9ICJtYXJrZXJzIiwNCiAgICAgIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDUsIGNvbG9yID0gImJsdWUiKSwNCiAgICAgIG5hbWUgPSAiUmVzaWR1YWwgU3VyZmFjZSINCiAgICApDQogIA0KICAjIFNldCB0aGUgbGF5b3V0IHdpdGggdGl0bGVzDQogIHBsb3QgPC0gcGxvdCAlPiUNCiAgICBsYXlvdXQoDQogICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiRGlzdGFuY2UgKG0pIiksDQogICAgICB5YXhpcyA9IGxpc3QoDQogICAgICAgIHRpdGxlID0gIkRlcHRoIChtKSIsDQogICAgICAgIHplcm9saW5lID0gRkFMU0UsDQogICAgICAgIHNob3dncmlkID0gRkFMU0UsDQogICAgICAgIHJhbmdlID0gYygtbWF4KHJlc2lkdWFscy5kZiRUaGFsd2VnX0RlcHRoX20sIG5hLnJtID0gVFJVRSksIDAuMDUpDQogICAgICApLA0KICAgICAgc2hvd2xlZ2VuZCA9IEZBTFNFLCAgIyBIaWRlIGxlZ2VuZCBmb3IgaW5kaXZpZHVhbCBwbG90cw0KICAgICAgYW5ub3RhdGlvbnMgPSBsaXN0KA0KICAgICAgICBsaXN0KA0KICAgICAgICAgIHggPSAwLjUsDQogICAgICAgICAgeSA9IDEuMSwNCiAgICAgICAgICB0ZXh0ID0gcGFzdGUoc2l0ZV95ZWFyKSwNCiAgICAgICAgICBzaG93YXJyb3cgPSBGQUxTRSwNCiAgICAgICAgICBmb250ID0gbGlzdChzaXplID0gMTQsIGZhbWlseSA9ICJBcmlhbCIsIGNvbG9yID0gImJsYWNrIiksDQogICAgICAgICAgeHJlZiA9ICJwYXBlciIsDQogICAgICAgICAgeXJlZiA9ICJwYXBlciINCiAgICAgICAgKQ0KICAgICAgKQ0KICAgICkNCiAgDQogIHBsb3RzW1tzaXRlX3llYXJdXSA8LSBwbG90DQp9DQoNCiMgRHVtbXkgcGxvdCBmb3IgYSBjb25zb2xpZGF0ZWQgbGVnZW5kIChhdHRlbXB0cyB0byBhdm9pZCByZXBldGl0aW9uIHVuZnJ1aXRmdWwgc28gZmFyKQ0KbGVnZW5kX3Bsb3QgPC0gcGxvdF9seSgpICU+JQ0KICBhZGRfc2VnbWVudHMoDQogICAgeCA9IGMoMSksICAjIER1bW15IHZhbHVlcw0KICAgIHhlbmQgPSBjKDEpLA0KICAgIHkgPSBjKDEpLA0KICAgIHllbmQgPSBjKDEpLA0KICAgIGNvbG9yID0gfmZhY3Rvcih1bmlxdWVfaGFiaXRhdF91bml0cywgbGV2ZWxzID0gdW5pcXVlX2hhYml0YXRfdW5pdHMpLA0KICAgIGNvbG9ycyA9IGhhYml0YXRfY29sb3JzLA0KICAgIHNob3dsZWdlbmQgPSBUUlVFDQopICU+JQ0KICBsYXlvdXQoDQogICAgbGVnZW5kID0gbGlzdCgNCiAgICAgIG9yaWVudGF0aW9uID0gImgiLA0KICAgICAgdGl0bGUgPSBsaXN0KHRleHQgPSAiPGI+SGFiaXRhdCBVbml0czwvYj4iKSwNCiAgICAgIHkgPSAtMC4zDQogICkNCikNCg0KIyBFeHRyYWN0IHVuaXF1ZSBTaXRlcyBhbmQgWWVhcnMNCnVuaXF1ZV9zaXRlcyA8LSB1bmlxdWUocmVzaWR1YWxzLmRmJFNpdGUpDQp1bmlxdWVfeWVhcnMgPC0gdW5pcXVlKHJlc2lkdWFscy5kZiR5ZWFyKQ0KDQojIERldGVybWluZSB0aGUgeS1heGlzIHJhbmdlIGJhc2VkIG9uIHRoZSBncmVhdGVzdCByYW5nZSBpbiBkYXRhDQp5X21pbiA8LSAtbWF4KHJlc2lkdWFscy5kZiRUaGFsd2VnX0RlcHRoX20sIG5hLnJtID0gVFJVRSkNCnlfbWF4IDwtIDAuMDUNCg0KIyBDcmVhdGUgbGlzdCBvZiBwbG90IGdyb3VwcyBieSBzaXRlDQpzaXRlX3Bsb3RzIDwtIGxpc3QoKQ0KDQpmb3IgKHNpdGUgaW4gdW5pcXVlX3NpdGVzKSB7DQogIHNpdGVfc3BlY2lmaWNfcGxvdHMgPC0gcGxvdHNbZ3JlcGwoc2l0ZSwgbmFtZXMocGxvdHMpKV0NCg0KICAjIEFycmFuZ2UgeWVhcnMgYXMgY29sdW1ucyBmb3IgZWFjaCBzaXRlIHJvdyAoc2l0ZSBhcyByb3cgc2VlbXMgcHJlZmVyYWJsZSBmb3IgeSBheGlzIGNvbXBhcmlzb25zKQ0KICBzaXRlX3Bsb3RzW1tzaXRlXV0gPC0gc3VicGxvdCgNCiAgICBzaXRlX3NwZWNpZmljX3Bsb3RzLA0KICAgIG5yb3dzID0gMSwgICMgT25lIHJvdyBmb3IgeWVhcnMsIG11bHRpcGxlIGNvbHVtbnMNCiAgICBzaGFyZVkgPSBUUlVFLA0KICAgIHRpdGxlWSA9IFRSVUUNCiAgKSAlPiUNCiAgICBsYXlvdXQoDQogICAgICB5YXhpcyA9IGxpc3QoDQogICAgICAgIHJhbmdlID0gYyh5X21pbiwgeV9tYXgpLCAgIyBGaXhlZCB5LWF4aXMgcmFuZ2UNCiAgICAgICAgdGl0bGUgPSAiRGVwdGggKG0pIiwNCiAgICAgICAgemVyb2xpbmUgPSBGQUxTRQ0KICAgICAgKQ0KICAgICkNCn0NCg0KIyBBcnJhbmdlIGVhY2ggc2l0ZSBpbiBpdHMgb3duIHJvdyB3aXRoIGNvbnNpc3RlbnQgeS1heGlzIHNjYWxpbmcNCmZpbmFsX3Bsb3QgPC0gc3VicGxvdCgNCiAgc2l0ZV9wbG90cywNCiAgbnJvd3MgPSBsZW5ndGgoc2l0ZV9wbG90cyksICAjIE9uZSByb3cgcGVyIHNpdGUNCiAgc2hhcmVYID0gVFJVRSwNCiAgdGl0bGVYID0gVFJVRQ0KKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gTlVMTCwgICMgUmVtb3ZlIHRoZSBvdmVyYWxsIGZpZ3VyZSB0aXRsZQ0KICAgIHNob3dsZWdlbmQgPSBGQUxTRSwNCiAgICBsZWdlbmQgPSBsaXN0KA0KICAgICAgdGl0bGUgPSBOVUxMLCAgIyBSZW1vdmUgbGVnZW5kIHRpdGxlDQogICAgICBvcmllbnRhdGlvbiA9ICJ2IiwNCiAgICAgIHggPSAxLjA1DQogICAgKQ0KICApDQoNCiMgRGlzcGxheSB0aGUgZmluYWwgcGxvdCB3aXRoIGFkanVzdG1lbnRzDQpmaW5hbF9wbG90DQoNCiMgRXhwb3J0IGluZGl2aWR1YWwgc2l0ZS15ZWFyIHBsb3RzDQpmb3IgKHNpdGVfeWVhciBpbiBuYW1lcyhwbG90cykpIHsNCiAgZmlsZW5hbWUgPC0gcGFzdGUwKCJIYWJpdGF0IFVuaXQgYW5kIERlcHRoICIsIHNpdGVfeWVhciwgIi5odG1sIikgICMgDQogIGV4cG9ydF9wbG90KHBsb3RzW1tzaXRlX3llYXJdXSwgZmlsZW5hbWUpDQp9DQoNCiMgRXhwb3J0IHRoZSBjb21wb3NpdGUgZmlndXJlDQpleHBvcnRfcGxvdChmaW5hbF9wbG90LCAiSGFiaXRhdCBVbml0cyBhbmQgRGVwdGggQWxsIFNpdGUgWWVhcnMuaHRtbCIpDQpgYGANCg0KQ2VydGFpbiBmZWF0dXJlcyBvZiB0aGUgYWJvdmUgZmlndXJlIG1heSBiZSBvZiBwYXJ0aWN1bGFyIGludGVyZXN0LiBGb3IgZXhhbXBsZSwgaWYgeW91ciByZWFjaCBjb250YWluZWQgREVCIChkZWJyaXMgZGFtbWVkIHBvb2xzKSBvciBCRUEgKGJlYXZlciBkYW1tZWQgcG9vbHMpLCB5b3UgY2FuIHNlZSBob3cgdGhlc2UgZmVhdHVyZXMgY29ycmVzcG9uZCB0byB0aGUgcmVzaWR1YWwgcG9vbHMgKHBvb2xzIHdoZXJlIGZsb3cgYXBwcm9hY2hlcyB6ZXJvKSBpbiB5b3VyIHJlYWNoLiBXZSBjYW4gYXNrIHdoYXQgcHJvcG9ydGlvbiBvZiByZWFjaCByZXNpZHVhbCBwb29sIGhhYml0YXQsIGJhc2VkIG9uIGhhYml0YXQgdW5pdCBhc3NpZ25tZW50cywgaXMgY29tcHJpc2VkIG9mIGJlYXZlciBvciBkZWJyaXMgZGFtbWVkIHBvb2xzLiBUaGlzIG1heSBiZSBvZiBwYXJ0aWN1bGFyIGludGVyZXN0IHdoZXJlIHByb2Nlc3MtYmFzZWQgcmVzdG9yYXRpb24gd29yayBoYXMgYmVlbiBpbml0aWF0ZWQuIA0KDQpGb3IgdGhpcyBxdWVzdGlvbiwgd2UgY29uc2lkZXIgYW55IHJlc2lkdWFsIHBvb2wgdGhhdCBpcyA1MCUgb3IgbW9yZSBhc3NpZ25lZCBhcyBCRUEgb3IgREVCIGFzIGJlaW5nIGEgYmVhdmVyIG9yIGRlYnJpcyBwb29sIGluIGl0cyBlbnRpcmV0eS4gU2ltaWxhcmx5LCBpZiB0aGUgZmllbGQgYXNzaWdubWVudCBvZiBCRUEgb3IgREVCIGNvcnJlc3BvbmRzIHdpdGggYSByZXNpZHVhbCBwb29sIG91dGxldCAoaS5lLiwgZGVicmlzIG9yIGEgYmVhdmVyIGRhbSB3YXMgb2JzZXJ2ZWQgaG9sZGluZyBiYWNrIHdhdGVyKSB0aGVuIHRoZSBlbnRpcmUgcmVzaWR1YWwgcG9vbCB3aWxsIGJlIGFzc2lnbmVkIGFzIGEgYmVhdmVyL2RlYnJpcyBkYW0gcG9vbCwgZXZlbiBpZiB0aGUgZnVsbCBleHRlbnQgd2FzIG5vdCByZWNvZ25pc2VkIGFzIHN1Y2ggaW4gdGhlIGZpZWxkLiBUaGlzIGFwcHJvYWNoIGlzIHRvIGFjY291bnQgZm9yIGRpZmZlcmVuY2VzIGJldHdlZW4gY29kZS1hc3NpZ25lZCByZXNpZHVhbCBwb29scyBhbmQgcG9vbHMgYXMgcmVjb2duaXNlZCBpbiB0aGUgZmllbGQsIHN1Y2ggYXMgd2hlcmUgYSBzZXF1ZW5jZSBvZiBiZWF2ZXIgcG9vbCwgZGVicmlzIHBvb2wsIHNjb3VyIHBvb2wgaXMgb2JzZXJ2ZWQsIGJ1dCBpbiBmYWN0IHRoZSB3aG9sZSBzZWN0aW9uIGFwcGVhcnMgdG8gYmUgY29udHJvbGxlZC9iYWNrd2F0ZXJlZCBieSB0aGUgZG93bnN0cmVhbSBiZWF2ZXIgZGFtLCBiYXNlZCBvbiB0aGUgcmVzaWR1YWwgc3VyZmFjZS4NCg0KQmVsb3cgd2UgZGlzcGxheSBhbmQgZXhwb3J0IHN1bW1hcnkgZGF0YSBmb3IgZWFjaCB5ZWFyIGF0IGVhY2ggcmVhY2gsIGFuZCB0aGUgaW5kaXZpZHVhbCBwb29sIGRhdGEgd2l0aCB0aGVpciBzdGF0dXMgYXMgYmVhdmVyL2RlYnJpcyBkYW0uIFdpdGggb3VyIEhhdGNoZXJ5IENoYW5uZWwgZXhhbXBsZSBkYXRhIHRoZXJlIGlzIG9uZSBkZWJyaXMgZGFtIHJlc2lkdWFsIHBvb2wgaWRlbnRpZmllZCBpbiAyMDI0IGJ1dCBub25lIGluIDIwMjUuIFdpdGggcmVmZXJlbmNlIHRvIHRoZSBhYm92ZSBmaWd1cmUsIHRoaXMgaXMgZXhwbGFpbmVkIGJ5IHRoZSB3b29keSBkZWJyaXMgYmVpbmcgYXQgdGhlIGxvY2F0aW9uIG9mIGEgcG9vbCBvdXRsZXQgaW4gMjAyNCwgYnV0IHRoZSBzYW1lIG1hZ25pdHVkZSBvZiBkZWJyaXMgaXMgbG9jYXRlZCBtaWQtcG9vbCBpbiAyMDI1IGFuZCBpcyB0aGVyZWZvcmUgY29uc2lkZXJlZCBub3QgdG8gYmUgZnVuY3Rpb25hbGx5IGNyZWF0aW5nIHRoZSBwb29sLg0KDQpgYGB7ciBwcm9wb3J0aW9uIEJFQS9ERUIgcG9vbHMsIGVjaG8gPSBGQUxTRSwgcmVzdWx0cz0nYXNpcyd9DQpjYWxjdWxhdGVfYmVhdmVyX2FuZF9kZWJyaXNfcG9vbHNfYnlfc2l0ZV95ZWFyIDwtIGZ1bmN0aW9uKGRmKSB7DQogICMgUmVtb3ZlIHJvd3Mgd2l0aCBOQSBwb29sX2lkcyBhbmQgbmVnYXRpdmUgZGlzdGFuY2VzDQogIGRmIDwtIGRmW2RmJGRpc3RhbmNlID49IDAgJiAhaXMubmEoZGYkcG9vbF9pZCksIF0NCiAgDQogICMgRW5zdXJlIHRoZSBkYXRhZnJhbWUgaXMgc29ydGVkIGJ5IFNpdGUsIHllYXIsIGFuZCBkaXN0YW5jZQ0KICBkZiA8LSBkZltvcmRlcihkZiRTaXRlLCBkZiR5ZWFyLCBkZiRkaXN0YW5jZSksIF0NCiAgDQogICMgU3BsaXQgdGhlIGRhdGEgYnkgU2l0ZS15ZWFyDQogIHNpdGVfeWVhcl9ncm91cHMgPC0gc3BsaXQoZGYsIGxpc3QoZGYkU2l0ZSwgZGYkeWVhciksIGRyb3AgPSBUUlVFKQ0KICANCiAgIyBJbml0aWFsaXplIHN0b3JhZ2UgZm9yIHNpdGUteWVhciBzdW1tYXJpZXMNCiAgc2l0ZV95ZWFyX3N1bW1hcnkgPC0gbGlzdCgpDQogIA0KICBmb3IgKHNpdGVfeWVhciBpbiBuYW1lcyhzaXRlX3llYXJfZ3JvdXBzKSkgew0KICAgICMgRXh0cmFjdCB0aGUgZGF0YSBmb3IgdGhlIGN1cnJlbnQgc2l0ZS15ZWFyDQogICAgc2l0ZV95ZWFyX2RhdGEgPC0gc2l0ZV95ZWFyX2dyb3Vwc1tbc2l0ZV95ZWFyXV0NCiAgICANCiAgICAjIElkZW50aWZ5IG91dGxldCBkZWJyaXMgY29uZGl0aW9ucw0KICAgIHNpdGVfeWVhcl9kYXRhJG91dGxldF9kZWJyaXMgPC0gd2l0aChzaXRlX3llYXJfZGF0YSwgaWZlbHNlKA0KICAgICAgKEhVX1ByaW1hcnkgJWluJSBjKCJCRUEiLCAiREVCIikpICYNCiAgICAgICAgKChwb29sX2lkICE9IGxhZyhwb29sX2lkLCBkZWZhdWx0ID0gZmlyc3QocG9vbF9pZCkpKSB8DQogICAgICAgICAocG9vbF9pZCAhPSBsYWcocG9vbF9pZCwgbiA9IDIsIGRlZmF1bHQgPSBmaXJzdChwb29sX2lkKSkpKSwNCiAgICAgICJZIiwNCiAgICAgICJOIg0KICAgICkpDQogICAgDQogICAgIyBJbml0aWFsaXplIHN0b3JhZ2UgZm9yIHBvb2wgY2xhc3NpZmljYXRpb24NCiAgICBwb29sX3N1bW1hcnkgPC0gbGlzdCgpDQogICAgDQogICAgIyBQcm9jZXNzIGVhY2ggdW5pcXVlIHBvb2xfaWQNCiAgICB1bmlxdWVfcG9vbF9pZHMgPC0gdW5pcXVlKHNpdGVfeWVhcl9kYXRhJHBvb2xfaWQpDQogICAgZm9yIChwb29sX2lkIGluIHVuaXF1ZV9wb29sX2lkcykgew0KICAgICAgIyBTdWJzZXQgZGF0YSBmb3IgdGhlIGN1cnJlbnQgcG9vbA0KICAgICAgcG9vbF9kYXRhIDwtIHNpdGVfeWVhcl9kYXRhW3NpdGVfeWVhcl9kYXRhJHBvb2xfaWQgPT0gcG9vbF9pZCwgXQ0KICAgICAgDQogICAgICAjIENhbGN1bGF0ZSB0aGUgbGVuZ3RoIG9mIHRoZSBwb29sDQogICAgICBwb29sX2xlbmd0aCA8LSBtYXgocG9vbF9kYXRhJGRpc3RhbmNlKSAtIG1pbihwb29sX2RhdGEkZGlzdGFuY2UpDQogICAgICANCiAgICAgICMgQ2FsY3VsYXRlIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSBwb29sJ3MgbGVuZ3RoIGZvciBlYWNoIGhhYml0YXQgdW5pdA0KICAgICAgaGFiaXRhdF9sZW5ndGhzIDwtIHBvb2xfZGF0YSAlPiUNCiAgICAgICAgZ3JvdXBfYnkoSFVfUHJpbWFyeSkgJT4lDQogICAgICAgIHN1bW1hcmlzZShsZW5ndGggPSBzdW0obGVhZChkaXN0YW5jZSwgZGVmYXVsdCA9IG1heChkaXN0YW5jZSkpIC0gZGlzdGFuY2UsIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpDQogICAgICANCiAgICAgICMgR2V0IGxlbmd0aHMgZm9yIEJFQSBhbmQgREVCLCBkZWZhdWx0aW5nIHRvIDAgaWYgbm90IHByZXNlbnQNCiAgICAgIGJlYV9sZW5ndGggPC0gaGFiaXRhdF9sZW5ndGhzJGxlbmd0aFtoYWJpdGF0X2xlbmd0aHMkSFVfUHJpbWFyeSA9PSAiQkVBIl0NCiAgICAgIGRlYl9sZW5ndGggPC0gaGFiaXRhdF9sZW5ndGhzJGxlbmd0aFtoYWJpdGF0X2xlbmd0aHMkSFVfUHJpbWFyeSA9PSAiREVCIl0NCiAgICAgIGJlYV9sZW5ndGggPC0gaWZlbHNlKGxlbmd0aChiZWFfbGVuZ3RoKSA9PSAwLCAwLCBiZWFfbGVuZ3RoKQ0KICAgICAgZGViX2xlbmd0aCA8LSBpZmVsc2UobGVuZ3RoKGRlYl9sZW5ndGgpID09IDAsIDAsIGRlYl9sZW5ndGgpDQogICAgICANCiAgICAgICMgQ2hlY2sgaWYgNTAlIG9yIG1vcmUgb2YgdGhlIHBvb2wncyBsZW5ndGggaXMgQkVBIG9yIERFQg0KICAgICAgaXNfYmVhdmVyX3Bvb2wgPC0gYmVhX2xlbmd0aCA+PSAwLjUgKiBwb29sX2xlbmd0aA0KICAgICAgaXNfZGVicmlzX3Bvb2wgPC0gZGViX2xlbmd0aCA+PSAwLjUgKiBwb29sX2xlbmd0aA0KICAgICAgDQogICAgICAjIENoZWNrIGlmIG91dGxldCBkZWJyaXMgY29uZGl0aW9uIGlzIG1ldA0KICAgICAgaGFzX2JlYXZlcl9vdXRsZXQgPC0gYW55KHBvb2xfZGF0YSRvdXRsZXRfZGVicmlzID09ICJZIiAmIHBvb2xfZGF0YSRIVV9QcmltYXJ5ID09ICJCRUEiKQ0KICAgICAgaGFzX2RlYnJpc19vdXRsZXQgPC0gYW55KHBvb2xfZGF0YSRvdXRsZXRfZGVicmlzID09ICJZIiAmIHBvb2xfZGF0YSRIVV9QcmltYXJ5ID09ICJERUIiKQ0KICAgICAgDQogICAgICAjIEFzc2lnbiBwb29sIHR5cGUgYmFzZWQgb24gaGFiaXRhdCBkb21pbmFuY2Ugb3Igb3V0bGV0IGRlYnJpcyBjb25kaXRpb24NCiAgICAgIHBvb2xfdHlwZSA8LSBpZiAoaXNfYmVhdmVyX3Bvb2wgfHwgaGFzX2JlYXZlcl9vdXRsZXQpIHsNCiAgICAgICAgIkJlYXZlciBQb29sIg0KICAgICAgfSBlbHNlIGlmIChpc19kZWJyaXNfcG9vbCB8fCBoYXNfZGVicmlzX291dGxldCkgew0KICAgICAgICAiRGVicmlzLURhbSBQb29sIg0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgIk90aGVyIg0KICAgICAgfQ0KICAgICAgDQogICAgICAjIENhbGN1bGF0ZSBzYWdpdHRhbCBhcmVhIGZvciB0aGUgcG9vbA0KICAgICAgc2FnaXR0YWxfYXJlYSA8LSAwDQogICAgICBmb3IgKGkgaW4gMToobnJvdyhwb29sX2RhdGEpIC0gMSkpIHsNCiAgICAgICAgZGVwdGggPC0gcG9vbF9kYXRhJHJlc2lkdWFsX2RlcHRoW2ldDQogICAgICAgIGlmIChpcy5uYShkZXB0aCkgfHwgZGVwdGggPD0gMCkgbmV4dA0KICAgICAgICBzcGFjaW5nIDwtIGFicyhwb29sX2RhdGEkZGlzdGFuY2VbaSArIDFdIC0gcG9vbF9kYXRhJGRpc3RhbmNlW2ldKQ0KICAgICAgICBzYWdpdHRhbF9hcmVhIDwtIHNhZ2l0dGFsX2FyZWEgKyAoZGVwdGggKiBzcGFjaW5nKQ0KICAgICAgfQ0KICAgICAgDQogICAgICAjIEhhbmRsZSBsYXN0IHJvdyBjb250cmlidXRpb24gdG8gc2FnaXR0YWwgYXJlYQ0KICAgICAgbGFzdF9yb3cgPC0gcG9vbF9kYXRhW25yb3cocG9vbF9kYXRhKSwgXQ0KICAgICAgaWYgKCFpcy5uYShsYXN0X3JvdyRyZXNpZHVhbF9kZXB0aCkgJiYgbGFzdF9yb3ckcmVzaWR1YWxfZGVwdGggPiAwKSB7DQogICAgICAgIG5leHRfcG9vbF9zdGFydCA8LSBzaXRlX3llYXJfZGF0YVtzaXRlX3llYXJfZGF0YSRkaXN0YW5jZSA+IGxhc3Rfcm93JGRpc3RhbmNlICYgIWlzLm5hKHNpdGVfeWVhcl9kYXRhJHBvb2xfaWQpLCBdDQogICAgICAgIGlmIChucm93KG5leHRfcG9vbF9zdGFydCkgPiAwKSB7DQogICAgICAgICAgbmV4dF9kaXN0YW5jZSA8LSBuZXh0X3Bvb2xfc3RhcnQkZGlzdGFuY2VbMV0NCiAgICAgICAgICBzcGFjaW5nIDwtIGFicyhuZXh0X2Rpc3RhbmNlIC0gbGFzdF9yb3ckZGlzdGFuY2UpDQogICAgICAgICAgc2FnaXR0YWxfYXJlYSA8LSBzYWdpdHRhbF9hcmVhICsgKGxhc3Rfcm93JHJlc2lkdWFsX2RlcHRoICogc3BhY2luZykNCiAgICAgICAgfQ0KICAgICAgfQ0KICAgICAgDQogICAgICAjIFN0b3JlIHJlc3VsdHMgZm9yIHRoZSBwb29sDQogICAgICBwb29sX3N1bW1hcnlbW2FzLmNoYXJhY3Rlcihwb29sX2lkKV1dIDwtIGxpc3QoDQogICAgICAgIHBvb2xfbGVuZ3RoID0gcG9vbF9sZW5ndGgsDQogICAgICAgIHNhZ2l0dGFsX2FyZWEgPSBzYWdpdHRhbF9hcmVhLA0KICAgICAgICBwb29sX3R5cGUgPSBwb29sX3R5cGUNCiAgICAgICkNCiAgICB9DQogICAgDQogICAgIyBDcmVhdGUgYSBkYXRhIGZyYW1lIGZyb20gdGhlIHBvb2wgc3VtbWFyeQ0KICAgIHBvb2xfc3VtbWFyeV9kZiA8LSBkYXRhLmZyYW1lKA0KICAgICAgcG9vbF9pZCA9IG5hbWVzKHBvb2xfc3VtbWFyeSksDQogICAgICBwb29sX2xlbmd0aCA9IHNhcHBseShwb29sX3N1bW1hcnksIGZ1bmN0aW9uKHgpIHgkcG9vbF9sZW5ndGgpLA0KICAgICAgc2FnaXR0YWxfYXJlYSA9IHNhcHBseShwb29sX3N1bW1hcnksIGZ1bmN0aW9uKHgpIHgkc2FnaXR0YWxfYXJlYSksDQogICAgICBwb29sX3R5cGUgPSBzYXBwbHkocG9vbF9zdW1tYXJ5LCBmdW5jdGlvbih4KSB4JHBvb2xfdHlwZSkNCiAgICApDQogICAgDQogICAgIyBDYWxjdWxhdGUgcHJvcG9ydGlvbnMgZm9yIHRoZSBjdXJyZW50IHNpdGUteWVhcg0KICAgIHRvdGFsX2xlbmd0aCA8LSBzdW0ocG9vbF9zdW1tYXJ5X2RmJHBvb2xfbGVuZ3RoKQ0KICAgIHRvdGFsX3NhZ2l0dGFsX2FyZWEgPC0gc3VtKHBvb2xfc3VtbWFyeV9kZiRzYWdpdHRhbF9hcmVhKQ0KICAgIA0KICAgIGJlYXZlcl9sZW5ndGggPC0gc3VtKHBvb2xfc3VtbWFyeV9kZiRwb29sX2xlbmd0aFtwb29sX3N1bW1hcnlfZGYkcG9vbF90eXBlID09ICJCZWF2ZXIgUG9vbCJdLCBuYS5ybSA9IFRSVUUpDQogICAgZGVicmlzX2xlbmd0aCA8LSBzdW0ocG9vbF9zdW1tYXJ5X2RmJHBvb2xfbGVuZ3RoW3Bvb2xfc3VtbWFyeV9kZiRwb29sX3R5cGUgPT0gIkRlYnJpcy1EYW0gUG9vbCJdLCBuYS5ybSA9IFRSVUUpDQogICAgDQogICAgYmVhdmVyX2FyZWEgPC0gc3VtKHBvb2xfc3VtbWFyeV9kZiRzYWdpdHRhbF9hcmVhW3Bvb2xfc3VtbWFyeV9kZiRwb29sX3R5cGUgPT0gIkJlYXZlciBQb29sIl0sIG5hLnJtID0gVFJVRSkNCiAgICBkZWJyaXNfYXJlYSA8LSBzdW0ocG9vbF9zdW1tYXJ5X2RmJHNhZ2l0dGFsX2FyZWFbcG9vbF9zdW1tYXJ5X2RmJHBvb2xfdHlwZSA9PSAiRGVicmlzLURhbSBQb29sIl0sIG5hLnJtID0gVFJVRSkNCiAgICANCiAgICBwcm9wb3J0aW9ucyA8LSBsaXN0KA0KICAgICAgdG90YWxfbGVuZ3RoID0gdG90YWxfbGVuZ3RoLA0KICAgICAgdG90YWxfc2FnaXR0YWxfYXJlYSA9IHRvdGFsX3NhZ2l0dGFsX2FyZWEsDQogICAgICBiZWF2ZXJfbGVuZ3RoX3Byb3AgPSBpZmVsc2UodG90YWxfbGVuZ3RoID4gMCwgYmVhdmVyX2xlbmd0aCAvIHRvdGFsX2xlbmd0aCwgMCksDQogICAgICBkZWJyaXNfbGVuZ3RoX3Byb3AgPSBpZmVsc2UodG90YWxfbGVuZ3RoID4gMCwgZGVicmlzX2xlbmd0aCAvIHRvdGFsX2xlbmd0aCwgMCksDQogICAgICBiZWF2ZXJfc2FnaXR0YWxfYXJlYV9wcm9wID0gaWZlbHNlKHRvdGFsX3NhZ2l0dGFsX2FyZWEgPiAwLCBiZWF2ZXJfYXJlYSAvIHRvdGFsX3NhZ2l0dGFsX2FyZWEsIDApLA0KICAgICAgZGVicmlzX3NhZ2l0dGFsX2FyZWFfcHJvcCA9IGlmZWxzZSh0b3RhbF9zYWdpdHRhbF9hcmVhID4gMCwgZGVicmlzX2FyZWEgLyB0b3RhbF9zYWdpdHRhbF9hcmVhLCAwKQ0KICAgICkNCiAgICANCiAgICAjIFN0b3JlIHRoZSByZXN1bHRzIGZvciB0aGUgY3VycmVudCBzaXRlLXllYXINCiAgICBzaXRlX3llYXJfc3VtbWFyeVtbc2l0ZV95ZWFyXV0gPC0gbGlzdCgNCiAgICAgIHN1bW1hcnlfdGFibGUgPSBwb29sX3N1bW1hcnlfZGYsDQogICAgICBwcm9wb3J0aW9ucyA9IHByb3BvcnRpb25zDQogICAgKQ0KICB9DQoNCiAgcmV0dXJuKHNpdGVfeWVhcl9zdW1tYXJ5KQ0KfQ0KDQojIEFwcGx5IHRoZSBmdW5jdGlvbg0KcmVzdWx0IDwtIGNhbGN1bGF0ZV9iZWF2ZXJfYW5kX2RlYnJpc19wb29sc19ieV9zaXRlX3llYXIocmVzaWR1YWxzLmRmKQ0KDQojIENvbnZlcnQgbGlzdCBvZiBwcm9wb3J0aW9ucyBpbnRvIGEgZGF0YSBmcmFtZQ0KcHJvcG9ydGlvbnNfZGYgPC0gZG8uY2FsbChyYmluZCwgbGFwcGx5KG5hbWVzKHJlc3VsdCksIGZ1bmN0aW9uKHNpdGVfeWVhcikgew0KICBkYXRhLmZyYW1lKHNpdGVfeWVhciA9IHNpdGVfeWVhciwgDQogICAgICAgICAgICAgdG90YWxfbGVuZ3RoID0gcmVzdWx0W1tzaXRlX3llYXJdXSRwcm9wb3J0aW9ucyR0b3RhbF9sZW5ndGgsDQogICAgICAgICAgICAgdG90YWxfc2FnaXR0YWxfYXJlYSA9IHJlc3VsdFtbc2l0ZV95ZWFyXV0kcHJvcG9ydGlvbnMkdG90YWxfc2FnaXR0YWxfYXJlYSwNCiAgICAgICAgICAgICBiZWF2ZXJfbGVuZ3RoX3Byb3AgPSByZXN1bHRbW3NpdGVfeWVhcl1dJHByb3BvcnRpb25zJGJlYXZlcl9sZW5ndGhfcHJvcCwNCiAgICAgICAgICAgICBkZWJyaXNfbGVuZ3RoX3Byb3AgPSByZXN1bHRbW3NpdGVfeWVhcl1dJHByb3BvcnRpb25zJGRlYnJpc19sZW5ndGhfcHJvcCwNCiAgICAgICAgICAgICBiZWF2ZXJfc2FnaXR0YWxfYXJlYV9wcm9wID0gcmVzdWx0W1tzaXRlX3llYXJdXSRwcm9wb3J0aW9ucyRiZWF2ZXJfc2FnaXR0YWxfYXJlYV9wcm9wLA0KICAgICAgICAgICAgIGRlYnJpc19zYWdpdHRhbF9hcmVhX3Byb3AgPSByZXN1bHRbW3NpdGVfeWVhcl1dJHByb3BvcnRpb25zJGRlYnJpc19zYWdpdHRhbF9hcmVhX3Byb3ApDQp9KSkNCg0KIyBkaXNwbGF5IHN1bW1hcnkgdGFibGUgaW4gUiAoYWxsIHNpdGVzIGFsbCB5ZWFycykNCmthYmxlKHByb3BvcnRpb25zX2RmLCBjYXB0aW9uID0gcGFzdGUoIkJlYXZlciBvciBEZWJyaXMgUG9vbHMgU3VtbWFyeSBBbGwgU2l0ZXMgWWVhcnMiKSwNCiAgICAgICAgICAgICBmb3JtYXQgPSAiaHRtbCIsIGRpZ2l0cyA9IDMpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UpDQoNCiMgRXhwb3J0IHRoZSBzdW1tYXJ5IHRhYmxlIGFsbCBTaXRlIFllYXJzDQpleHBvcnRfdGFibGUocHJvcG9ydGlvbnNfZGYsICJCZWF2ZXIgRGVicmlzIFBvb2wgUmVhY2ggUHJvcG9ydGlvbnMuY3N2IikNCg0KIyBFeHBvcnQgaW5kaXZpZHVhbCBzaXRlLXllYXIgdGFibGVzIA0KZm9yIChzaXRlX3llYXIgaW4gbmFtZXMocmVzdWx0KSkgew0KICBzaXRlX3llYXJfdGFibGUgPC0gcmVzdWx0W1tzaXRlX3llYXJdXSRzdW1tYXJ5X3RhYmxlDQogIA0KICAjIEVuc3VyZSB3ZSBhcmUgZXhwb3J0aW5nIG9ubHkgdGhlIHJhdyBkYXRhDQogIGlmICghaXMuZGF0YS5mcmFtZShzaXRlX3llYXJfdGFibGUpKSB7DQogICAgc2l0ZV95ZWFyX3RhYmxlIDwtIGFzLmRhdGEuZnJhbWUoc2l0ZV95ZWFyX3RhYmxlKQ0KICB9DQogIA0KICAjIEV4dHJhY3QgU2l0ZSBhbmQgWWVhciBmcm9tIHNpdGVfeWVhcg0KICBzaXRlX2luZm8gPC0gdW5saXN0KHN0cnNwbGl0KHNpdGVfeWVhciwgIlsuXSIpKSAgDQogIHNpdGVfbmFtZSA8LSBzaXRlX2luZm9bMV0NCiAgeWVhciA8LSBzaXRlX2luZm9bMl0NCiAgDQogICMgRGVmaW5lIGZpbGVuYW1lIGR5bmFtaWNhbGx5DQogIGZpbGVuYW1lIDwtIHBhc3RlMCgiQmVhdmVyIG9yIERlYnJpcyBQb29scyAiLCBzaXRlX3llYXIsICIuY3N2IikNCiAgDQogICMgV3JpdGUgdG8gQ1NWIHVzaW5nIHRoZSBmdW5jdGlvbg0KICBleHBvcnRfdGFibGUoc2l0ZV95ZWFyX3RhYmxlLCBmaWxlbmFtZSkNCiAgDQojIHByaW50IHRhYmxlcyBpbiBSIA0KIHByaW50KGthYmxlKHNpdGVfeWVhcl90YWJsZSwgY2FwdGlvbiA9IHBhc3RlKCJCZWF2ZXIgb3IgRGVicmlzIFBvb2xzICIsIHNpdGVfbmFtZSwgIiAiLCB5ZWFyKSwNCiAgICAgICAgICAgICBmb3JtYXQgPSAiaHRtbCIsIGRpZ2l0cyA9IDMpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpLCBmdWxsX3dpZHRoID0gRkFMU0UpKQ0KfQ0KYGBgDQoNCkEgc3VtbWFyeSBmaWd1cmUgaXMgYWxzbyBnZW5lcmF0ZWQgYW5kIGV4cG9ydGVkIHRvIHlvdXIgb3V0cHV0IGZvbGRlci4gVGhlIGNvbXBvc2l0ZSBmaWd1cmUgZGlzcGxheXMgdGhlIHJlYWNod2lkZSBwcm9wb3J0aW9uIG9mIHJlc2lkdWFsIHBvb2wgbGVuZ3RoL3NhZ2l0dGFsIGFyZWEgdGhhdCBpcyBjb21wcmlzZWQgb2YgYmVhdmVyIGFuZCBkZWJyaXMgZGFtbWVkIHBvb2xzLCBmb3IgZWFjaCByZWFjaCBhY3Jvc3MgdGltZS4NCg0KYGBge3IgQkVBL0RFQiBzdW1tYXJ5IHBsb3RzLCBlY2hvID0gRkFMU0V9DQojIFByZXBhcmUgZGF0YSBmb3IgcGxvdHRpbmcNCnBsb3RfZGF0YSA8LSBkby5jYWxsKHJiaW5kLCBsYXBwbHkobmFtZXMocmVzdWx0KSwgZnVuY3Rpb24oc2l0ZV95ZWFyKSB7DQogIHNpdGVfeWVhcl9zcGxpdCA8LSBzdHJzcGxpdChzaXRlX3llYXIsICJcXC4iKVtbMV1dDQogIFNpdGUgPC0gc2l0ZV95ZWFyX3NwbGl0WzFdDQogIHllYXIgPC0gc2l0ZV95ZWFyX3NwbGl0WzJdDQogIA0KICBwcm9wb3J0aW9ucyA8LSByZXN1bHRbW3NpdGVfeWVhcl1dJHByb3BvcnRpb25zDQogIGRhdGEuZnJhbWUoDQogICAgU2l0ZSA9IFNpdGUsDQogICAgeWVhciA9IGZhY3Rvcih5ZWFyKSwgICMgQ29udmVydCB5ZWFyIHRvIGZhY3RvciBmb3IgeC1heGlzDQogICAgYmVhdmVyX2xlbmd0aF9wcm9wID0gcHJvcG9ydGlvbnMkYmVhdmVyX2xlbmd0aF9wcm9wLA0KICAgIGRlYnJpc19sZW5ndGhfcHJvcCA9IHByb3BvcnRpb25zJGRlYnJpc19sZW5ndGhfcHJvcCwNCiAgICBiZWF2ZXJfc2FnaXR0YWxfYXJlYV9wcm9wID0gcHJvcG9ydGlvbnMkYmVhdmVyX3NhZ2l0dGFsX2FyZWFfcHJvcCwNCiAgICBkZWJyaXNfc2FnaXR0YWxfYXJlYV9wcm9wID0gcHJvcG9ydGlvbnMkZGVicmlzX3NhZ2l0dGFsX2FyZWFfcHJvcA0KICApDQp9KSkNCg0KIyBDb252ZXJ0IGRhdGEgdG8gbG9uZyBmb3JtYXQgZm9yIGZhY2V0aW5nDQpwbG90X2RhdGFfbG9uZyA8LSBwbG90X2RhdGEgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhiZWF2ZXJfbGVuZ3RoX3Byb3AsIGRlYnJpc19sZW5ndGhfcHJvcCwgDQogICAgICAgICAgICAgICAgICAgICAgICBiZWF2ZXJfc2FnaXR0YWxfYXJlYV9wcm9wLCBkZWJyaXNfc2FnaXR0YWxfYXJlYV9wcm9wKSwgDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJNZXRyaWMiLCB2YWx1ZXNfdG8gPSAiUHJvcG9ydGlvbiIpICU+JQ0KICBtdXRhdGUoDQogICAgUG9vbF9UeXBlID0gY2FzZV93aGVuKA0KICAgICAgTWV0cmljID09ICJiZWF2ZXJfbGVuZ3RoX3Byb3AiIH4gIkJlYXZlciBQb29sIiwNCiAgICAgIE1ldHJpYyA9PSAiZGVicmlzX2xlbmd0aF9wcm9wIiB+ICJEZWJyaXMgUG9vbCIsDQogICAgICBNZXRyaWMgPT0gImJlYXZlcl9zYWdpdHRhbF9hcmVhX3Byb3AiIH4gIkJlYXZlciBQb29sIiwNCiAgICAgIE1ldHJpYyA9PSAiZGVicmlzX3NhZ2l0dGFsX2FyZWFfcHJvcCIgfiAiRGVicmlzIFBvb2wiDQogICAgKSwNCiAgICBQcm9wb3J0aW9uX1R5cGUgPSBjYXNlX3doZW4oDQogICAgICBzdHJfZGV0ZWN0KE1ldHJpYywgImxlbmd0aCIpIH4gIlByb3BvcnRpb24gb2YgUmVhY2ggUmVzaWR1YWwgUG9vbCBUb3RhbCBMZW5ndGgiLA0KICAgICAgc3RyX2RldGVjdChNZXRyaWMsICJzYWdpdHRhbF9hcmVhIikgfiAiUHJvcG9ydGlvbiBvZiBSZWFjaCBSZXNpZHVhbCBQb29sIFRvdGFsIFNhZ2l0dGFsIEFyZWEiDQogICAgKQ0KICApDQoNCiMgaG9sbG93IHNoYXBlIGNvZGVzDQpzaGFwZV92YWx1ZXMgPC0gYygiQmVhdmVyIFBvb2wiID0gMjEsICJEZWJyaXMgUG9vbCIgPSAyNCkgDQoNCiMgQ3JlYXRlIHRoZSBjb21wb3NpdGUgZmFjZXRlZCBwbG90DQpkYW1fcGxvdDwtZ2dwbG90KHBsb3RfZGF0YV9sb25nLCBhZXMoeCA9IHllYXIsIHkgPSBQcm9wb3J0aW9uLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gUG9vbF9UeXBlLCBsaW5ldHlwZSA9IFBvb2xfVHlwZSwgc2hhcGUgPSBQb29sX1R5cGUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSBpbnRlcmFjdGlvbihTaXRlLCBQb29sX1R5cGUpKSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSA0LCBzdHJva2UgPTEuMykgKyAgDQogIGdlb21fbGluZShsaW5ld2lkdGggPSAxLjEpICsgIA0KICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gc2hhcGVfdmFsdWVzKSArICAjIEFwcGx5ICBob2xsb3cgc2hhcGVzDQogIGZhY2V0X2dyaWQocm93cyA9IHZhcnMoU2l0ZSksIGNvbHMgPSB2YXJzKFByb3BvcnRpb25fVHlwZSkpICsNCiAgeWxpbSgwLCAxKSArICAjIFNldCB5LWF4aXMgcmFuZ2UgdG8gMC0xIGZvciBhbGwgcGxvdHMNCiAgbGFicygNCiAgICB4ID0gIlllYXIiLCANCiAgICB5ID0gIlByb3BvcnRpb24iLA0KICAgIHRpdGxlID0gIlJlc2lkdWFsIFBvb2wgUHJvcG9ydGlvbnMgRm9ybWVkIGJ5IEJlYXZlciBvciBEZWJyaXMgRGFtcyIsDQogICAgY29sb3IgPSAiUG9vbCBUeXBlIiwNCiAgICBzaGFwZSA9ICJQb29sIFR5cGUiLA0KICAgIGxpbmV0eXBlID0gIlBvb2wgVHlwZSINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLA0KICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbGluZXdpZHRoID0gMC41KSwgDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCmRhbV9wbG90DQojZXhwb3J0IGZpZ3VyZSBwZGYNCmV4cG9ydF9wbG90KGRhbV9wbG90LCAiQmVhdmVyIERlYnJpcyBEYW0gUG9vbHMucGRmIikNCmBgYA0KDQojIEhhYml0YXQgVW5pdCBEaXZlcnNpdHkNCg0KTm93IGxldCdzIHRha2UgYSBsb29rIGF0IGRpdmVyc2l0eSBtZXRyaWNzIGZvciB0aGUgaGFiaXRhdCB1bml0cyBhc3NpZ25lZCBpbiB0aGUgZmllbGQuIFdoZW4gd2UgcmVmZXIgdG8gcG9vbHMgaGVyZSwgd2UgYXJlIHJlZmVycmluZyBvbmx5IHRvIGhhYml0YXQgYXNzaWduZWQgaW4gdGhlIGZpZWxkLCBhbmQgbm90IHRoZSByZXNpZHVhbCBwb29scyB0aGF0IHdlIGlkZW50aWZpZWQgaW4gb3VyIHByZXZpb3VzIHNjcmlwdC4gUmVtZW1iZXIgdGhhdCB3aGlsZSByZXNpZHVhbCBwb29scyBhcmUgYW4gZXN0aW1hdGUgb2YgaGFiaXRhdCB3aGVuIGZsb3cgYXBwcm9hY2hlcyB6ZXJvLCB0aGUgcG9vbHMgYXNzaWduZWQgaW4gdGhlIGZpZWxkIHJlcHJlc2VudCBoYWJpdGF0IGFzIG9ic2VydmFibGUgYXQgdGhhdCBwYXJ0aWN1bGFyIGZsb3cgY29uZGl0aW9uLg0KDQpCZWZvcmUgcmVhZGluZyBpbnRvIHRoZSBiZWxvdyBtZXRyaWNzLCBpdCBpcyB3b3J0aCBjb25zaWRlcmluZyB0aGF0IHBlb3BsZSBjbGFzc2lmeWluZyBIYWJpdGF0IFVuaXRzIG1heSB2YXJ5IGluIGV4cGVyaWVuY2UgYW5kL29yIGNvbmZpZGVuY2UsIGFuZCBjb3VsZCAoZm9yIGV4YW1wbGUpICdkZWZhdWx0JyB0byBhIHBhcnRpY3VsYXIgdHlwZSBvZiBwb29sIHRoYXQgdGhleSBhcmUgbW9zdCBmYW1pbGlhciB3aGVuIHRoZXkgYXJlIHVuc3VyZS4gVGhpcyBjb3VsZCBtZWFuIHRoYXQgaWRlbnRpY2FsIGhhYml0YXRzIGNhbiBkaWZmZXIgaW4gY2VydGFpbiBtZXRyaWNzIGJhc2VkIG9uIHRoZSBvYnNlcnZlci4gV2UgZmVlbCB0aGF0IHBvb2wgcGVyY2VudCBhbmQgcG9vbC10by1yaWZmbGUgcmF0aW8gYXJlIHJvYnVzdCB0byB0aGVzZSBjb25jZXJucywgdGhhdCBzY291cmVkIGFuZCBkYW1tZWQgcG9vbCBwZXJjZW50YWdlcyBhcmUgZmFpcmx5IHJvYnVzdCBpbiB0aGUgbWFqb3JpdHkgb2YgY2FzZXMsIGJ1dCB0aGF0IHRoZSBTaGFubm9uIGRpdmVyc2l0eSBpbmRleCBpcyBwcm9uZSB0byB1bmRlcmVzdGltYXRlcyBvZiBkaXZlcnNpdHkgaWYgb2JzZXJ2ZXJzIGFyZSBub3QgY29uZmlkZW50IGFzc2lnbmluZyBhbnkgb2YgdGhlIGFwcHJvcHJpYXRlIGhhYml0YXQgdW5pdCBjYXRlZ29yaWVzLiBBcyBzdWNoLCBleGVyY2lzZSBleHRyYSBjYXV0aW9uIHdpdGggaW50ZXJwcmV0aW5nIGNoYW5nZXMgaW4gU2hhbm5vbiBpbmRpY2VzIHdoZXJlIG9ic2VydmVycyBoYXZlIGNoYW5nZWQgb3ZlciB0aW1lIG9yIGJldHdlZW4gcmVhY2hlcyAob3IgZXZlbiBpZiBzaWduaWZpY2FudCB0aW1lIGhhcyBwYXNzZWQgZm9yIHRoZSBzYW1lIG9ic2VydmVyKS4NCg0KYGBge3IgaGFiaXRhdCB1bml0IGRpdmVyc2l0eSwgZWNobyA9IEZBTFNFfQ0KY2FsY3VsYXRlX2RpdmVyc2l0eV9hbmRfYXJlYV9tZXRyaWNzX2J5X3NpdGVfeWVhciA8LSBmdW5jdGlvbihkZikgew0KICAjIFJlbW92ZSByb3dzIHdpdGggTkEgb3IgbmVnYXRpdmUgZGlzdGFuY2VzDQogIGRmIDwtIGRmW2RmJGRpc3RhbmNlID49IDAgJiAhaXMubmEoZGYkcG9vbF9pZCksIF0NCiAgDQogICMgQ3JlYXRlIGEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHNpdGUteWVhciBjb21iaW5hdGlvbnMsIHNwbGl0IGJ5IHNpdGUteWVhcg0KICBkZiRzaXRlX3llYXIgPC0gcGFzdGUoZGYkU2l0ZSwgZGYkeWVhciwgc2VwID0gIi4iKQ0KICBzcGxpdF9kYXRhIDwtIHNwbGl0KGRmLCBkZiRzaXRlX3llYXIpDQogIA0KICAjIEZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBtZXRyaWNzIGZvciBlYWNoIHN1YnNldA0KICBjYWxjdWxhdGVfbWV0cmljcyA8LSBmdW5jdGlvbihzdWJfZGYpIHsNCiAgICAjIFNoYW5ub24gRGl2ZXJzaXR5IEluZGV4IGZvciBIVV9QcmltYXJ5DQogICAgaHVfY291bnRzIDwtIHRhYmxlKHN1Yl9kZiRIVV9QcmltYXJ5KQ0KICAgIGh1X3Byb3BvcnRpb25zIDwtIGh1X2NvdW50cyAvIHN1bShodV9jb3VudHMpDQogICAgc2hhbm5vbl9pbmRleCA8LSAtc3VtKGh1X3Byb3BvcnRpb25zICogbG9nKGh1X3Byb3BvcnRpb25zKSwgbmEucm0gPSBUUlVFKQ0KICAgIA0KICAgICMgUG9vbCBQZXJjZW50IChiYXNlZCBvbiBiYXJfd2lkdGgpDQogICAgcG9vbF9odSA8LSBjKCJFRCIsICJUUiIsICJNSUQiLCAiQ09OIiwgIkxBVCIsICJQTCIsICJERUIiLCAiQkVBIiwgIkxBTiIsICJCQUMiLCAiQUIiLCAiU0xPVyIpDQogICAgcG9vbF9hcmVhX2RmIDwtIHN1Yl9kZltzdWJfZGYkSFVfUHJpbWFyeSAlaW4lIHBvb2xfaHUsIF0NCiAgICB0b3RhbF9wb29sX2FyZWEgPC0gc3VtKHBvb2xfYXJlYV9kZiRiYXJfd2lkdGgpICAjIFN1bSBvZiBiYXJfd2lkdGggZm9yIHBvb2wgdHlwZXMNCiAgICANCiAgICAjIFNjb3VyZWQgUG9vbCBQZXJjZW50IChiYXNlZCBvbiBiYXJfd2lkdGgpDQogICAgc2NvdXJlZF9odSA8LSBjKCJFRCIsICJUUiIsICJNSUQiLCAiQ09OIiwgIkxBVCIsICJQTCIpDQogICAgc2NvdXJlZF9hcmVhX2RmIDwtIHN1Yl9kZltzdWJfZGYkSFVfUHJpbWFyeSAlaW4lIHNjb3VyZWRfaHUsIF0NCiAgICB0b3RhbF9zY291cmVkX2FyZWEgPC0gc3VtKHNjb3VyZWRfYXJlYV9kZiRiYXJfd2lkdGgpDQogICAgDQogICAgIyBEYW1tZWQgUG9vbCBQZXJjZW50IChiYXNlZCBvbiBiYXJfd2lkdGgpDQogICAgZGFtbWVkX2h1IDwtIGMoIkRFQiIsICJCRUEiLCAiTEFOIiwgIkJBQyIsICJBQiIsICJTTE9XIikNCiAgICBkYW1tZWRfYXJlYV9kZiA8LSBzdWJfZGZbc3ViX2RmJEhVX1ByaW1hcnkgJWluJSBkYW1tZWRfaHUsIF0NCiAgICB0b3RhbF9kYW1tZWRfYXJlYSA8LSBzdW0oZGFtbWVkX2FyZWFfZGYkYmFyX3dpZHRoKQ0KICAgIA0KICAgICMgVG90YWwgYXJlYSAoZGlzdGFuY2UgcmFuZ2UgaW4gdGhlIGRhdGFmcmFtZSkNCiAgICB0b3RhbF9hcmVhIDwtIG1heChzdWJfZGYkZGlzdGFuY2UpIC0gbWluKHN1Yl9kZiRkaXN0YW5jZSkNCiAgICANCiAgICAjIFBvb2wgdG8gUmlmZmxlIFJhdGlvDQogICAgcmlmZmxlX2h1IDwtICJSSUYiDQogICAgcG9vbF9odV9mb3JfcmF0aW8gPC0gcG9vbF9odQ0KICAgIHBvb2xfYXJlYV9mb3JfcmF0aW9fZGYgPC0gc3ViX2RmW3N1Yl9kZiRIVV9QcmltYXJ5ICVpbiUgcG9vbF9odV9mb3JfcmF0aW8sIF0NCiAgICByaWZmbGVfYXJlYV9kZiA8LSBzdWJfZGZbc3ViX2RmJEhVX1ByaW1hcnkgPT0gcmlmZmxlX2h1LCBdDQogICAgDQogICAgdG90YWxfcG9vbF9hcmVhX2Zvcl9yYXRpbyA8LSBzdW0ocG9vbF9hcmVhX2Zvcl9yYXRpb19kZiRiYXJfd2lkdGgpDQogICAgdG90YWxfcmlmZmxlX2FyZWEgPC0gc3VtKHJpZmZsZV9hcmVhX2RmJGJhcl93aWR0aCkNCiAgICANCiAgICBwb29sX3RvX3JpZmZsZV9yYXRpbyA8LSBpZmVsc2UodG90YWxfcmlmZmxlX2FyZWEgPiAwLCB0b3RhbF9wb29sX2FyZWFfZm9yX3JhdGlvIC8gdG90YWxfcmlmZmxlX2FyZWEsIDApDQogICAgDQogICAgIyBDYWxjdWxhdGUgcGVyY2VudGFnZXMgYmFzZWQgb24gYmFyX3dpZHRoDQogICAgcG9vbF9wZXJjZW50IDwtIGlmZWxzZSh0b3RhbF9hcmVhID4gMCwgdG90YWxfcG9vbF9hcmVhIC8gdG90YWxfYXJlYSAqIDEwMCwgMCkNCiAgICBzY291cnBvb2xfcGVyY2VudCA8LSBpZmVsc2UodG90YWxfYXJlYSA+IDAsIHRvdGFsX3Njb3VyZWRfYXJlYSAvIHRvdGFsX2FyZWEgKiAxMDAsIDApDQogICAgZGFtbWVkcG9vbF9wZXJjZW50IDwtIGlmZWxzZSh0b3RhbF9hcmVhID4gMCwgdG90YWxfZGFtbWVkX2FyZWEgLyB0b3RhbF9hcmVhICogMTAwLCAwKQ0KICAgIA0KICAgICMgUmV0dXJuIG1ldHJpY3MgYXMgYSBuYW1lZCB2ZWN0b3INCiAgICBjKA0KICAgICAgc2hhbm5vbl9kaXZlcnNpdHlfaW5kZXggPSBzaGFubm9uX2luZGV4LA0KICAgICAgcG9vbF9wZXJjZW50ID0gcG9vbF9wZXJjZW50LA0KICAgICAgc2NvdXJwb29sX3BlcmNlbnQgPSBzY291cnBvb2xfcGVyY2VudCwNCiAgICAgIGRhbW1lZHBvb2xfcGVyY2VudCA9IGRhbW1lZHBvb2xfcGVyY2VudCwNCiAgICAgIHBvb2xfdG9fcmlmZmxlX3JhdGlvID0gcG9vbF90b19yaWZmbGVfcmF0aW8NCiAgICApDQogIH0NCiAgDQogICMgQXBwbHkgdGhlIG1ldHJpYyBjYWxjdWxhdGlvbiBmdW5jdGlvbiB0byBlYWNoIHNpdGUteWVhcg0KICByZXN1bHRzIDwtIGxhcHBseShzcGxpdF9kYXRhLCBjYWxjdWxhdGVfbWV0cmljcykNCiAgDQogICMgQ29tYmluZSByZXN1bHRzIGludG8gYSBkYXRhIGZyYW1lIHdpdGggbWV0cmljcyBhcyBjb2x1bW5zDQogIHJlc3VsdHNfZGYgPC0gZG8uY2FsbChyYmluZCwgbGFwcGx5KG5hbWVzKHJlc3VsdHMpLCBmdW5jdGlvbihzaXRlX3llYXIpIHsNCiAgICBtZXRyaWNzIDwtIHJlc3VsdHNbW3NpdGVfeWVhcl1dDQogICAgc2l0ZV95ZWFyX3NwbGl0IDwtIHN0cnNwbGl0KHNpdGVfeWVhciwgIlxcLiIpW1sxXV0NCiAgICBkYXRhLmZyYW1lKA0KICAgICAgU2l0ZSA9IHNpdGVfeWVhcl9zcGxpdFsxXSwNCiAgICAgIHllYXIgPSBzaXRlX3llYXJfc3BsaXRbMl0sDQogICAgICBzaGFubm9uX2RpdmVyc2l0eV9pbmRleCA9IG1ldHJpY3NbInNoYW5ub25fZGl2ZXJzaXR5X2luZGV4Il0sDQogICAgICBwb29sX3BlcmNlbnQgPSBtZXRyaWNzWyJwb29sX3BlcmNlbnQiXSwNCiAgICAgIHNjb3VycG9vbF9wZXJjZW50ID0gbWV0cmljc1sic2NvdXJwb29sX3BlcmNlbnQiXSwNCiAgICAgIGRhbW1lZHBvb2xfcGVyY2VudCA9IG1ldHJpY3NbImRhbW1lZHBvb2xfcGVyY2VudCJdLA0KICAgICAgcG9vbF90b19yaWZmbGVfcmF0aW8gPSBtZXRyaWNzWyJwb29sX3RvX3JpZmZsZV9yYXRpbyJdDQogICAgKQ0KICB9KSkNCiAgDQogICMgRW5zdXJlIG51bWVyaWMgY29sdW1ucyBhcmUgY29ycmVjdGx5IGZvcm1hdHRlZA0KICByZXN1bHRzX2RmIDwtIHJlc3VsdHNfZGYgJT4lDQogICAgbXV0YXRlKGFjcm9zcyhjKHNoYW5ub25fZGl2ZXJzaXR5X2luZGV4OnBvb2xfdG9fcmlmZmxlX3JhdGlvKSwgYXMubnVtZXJpYykpDQogIA0KICAjIFJlbW92ZSByb3cgbmFtZXMNCiAgcm93bmFtZXMocmVzdWx0c19kZikgPC0gTlVMTA0KICANCiAgcmV0dXJuKHJlc3VsdHNfZGYpDQp9DQoNCiMgRXhhbXBsZSBvZiBydW5uaW5nIHRoZSBmdW5jdGlvbiBvbiB5b3VyIGRhdGFmcmFtZQ0KcmVzdWx0IDwtIGNhbGN1bGF0ZV9kaXZlcnNpdHlfYW5kX2FyZWFfbWV0cmljc19ieV9zaXRlX3llYXIocmVzaWR1YWxzLmRmKQ0KDQojIGRpc3BsYXkgc3VtbWFyeSB0YWJsZSBpbiBSIA0Ka2FibGUocmVzdWx0LCBjYXB0aW9uID0gcGFzdGUoIkhhYml0YXQgVW5pdCBEaXZlcnNpdHkgTWV0cmljcyIpLA0KICAgICAgICAgICAgIGZvcm1hdCA9ICJodG1sIiwgZGlnaXRzID0gMykgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIsICJyZXNwb25zaXZlIiksIGZ1bGxfd2lkdGggPSBGQUxTRSkNCg0KIyBFeHBvcnQgdGhlIHN1bW1hcnkgdGFibGUNCmV4cG9ydF90YWJsZShyZXN1bHQsICJIYWJpdGF0IFVuaXQgRGl2ZXJzaXR5IE1ldHJpY3MuY3N2IikNCmBgYA0KDQpgYGB7ciBIVSBtZXRyaWMgcGxvdHMsIGVjaG8gPSBGQUxTRX0NCiMgQ29udmVydCByZXN1bHRzIGRhdGFmcmFtZSB0byBsb25nIGZvcm1hdA0KcGxvdF9kYXRhX2xvbmcgPC0gcmVzdWx0ICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGMoc2hhbm5vbl9kaXZlcnNpdHlfaW5kZXgsIHBvb2xfdG9fcmlmZmxlX3JhdGlvKSwgDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJNZXRyaWMiLCB2YWx1ZXNfdG8gPSAiVmFsdWUiKSAlPiUNCiAgbXV0YXRlKA0KICAgIE1ldHJpY19MYWJlbCA9IGNhc2Vfd2hlbigNCiAgICAgIE1ldHJpYyA9PSAic2hhbm5vbl9kaXZlcnNpdHlfaW5kZXgiIH4gIlNoYW5ub24gRGl2ZXJzaXR5IEluZGV4IiwNCiAgICAgIE1ldHJpYyA9PSAicG9vbF90b19yaWZmbGVfcmF0aW8iIH4gIlBvb2wgdG8gUmlmZmxlIFJhdGlvIg0KICAgICkNCiAgKQ0KDQojIENvbWJpbmVkIGZhY2V0ZWQgcGxvdCB3aXRoIGF4aXMgbGluZXMNCkhVcGxvdHM8LWdncGxvdChwbG90X2RhdGFfbG9uZywgYWVzKHggPSBmYWN0b3IoeWVhciksIHkgPSBWYWx1ZSwgY29sb3IgPSBTaXRlLCBncm91cCA9IFNpdGUpKSArDQogIGdlb21fbGluZShsaW5ld2lkdGggPSAxLjIpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMykgKw0KICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKE1ldHJpY19MYWJlbCksIGNvbHMgPSB2YXJzKFNpdGUpLCBzY2FsZXMgPSAiZnJlZV95IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlNoYW5ub24gRGl2ZXJzaXR5IEluZGljZXMgYW5kIFBvb2wgdG8gUmlmZmxlIFJhdGlvcyBieSBTaXRlIGFuZCBZZWFyIiwNCiAgICB4ID0gIlllYXIiLA0KICAgIHkgPSAiVmFsdWUiLA0KICAgIGNvbG9yID0gIlNpdGUiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwNCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwNCiAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEsIGxpbmV3aWR0aCA9IDAuNSksIA0KICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkgICMgKipSZW1vdmVzIGdyaWQgbGluZXMqKg0KICApDQoNCiMjIyMjIyMjIyMjIyMgcGxvdCBvZiBwb29sIHR5cGUgcHJvcG9ydGlvbnMgDQojIFByZXBhcmUgZGF0YSBmb3IgdGhlIHN0YWNrZWQgYmFyIHBsb3QNCnBsb3RfZGF0YV9sb25nX3BlcmNlbnQgPC0gcmVzdWx0ICU+JQ0KICBzZWxlY3QoU2l0ZSwgeWVhciwgcG9vbF9wZXJjZW50LCBzY291cnBvb2xfcGVyY2VudCwgZGFtbWVkcG9vbF9wZXJjZW50KSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKHBvb2xfcGVyY2VudCwgc2NvdXJwb29sX3BlcmNlbnQsIGRhbW1lZHBvb2xfcGVyY2VudCksDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJQb29sX1R5cGUiLCB2YWx1ZXNfdG8gPSAiUHJvcG9ydGlvbiIpICU+JQ0KICBtdXRhdGUoUG9vbF9UeXBlX0xhYmVsID0gY2FzZV93aGVuKA0KICAgIFBvb2xfVHlwZSA9PSAicG9vbF9wZXJjZW50IiB+ICJQb29sIFBlcmNlbnQiLA0KICAgIFBvb2xfVHlwZSA9PSAic2NvdXJwb29sX3BlcmNlbnQiIH4gIlNjb3VycG9vbCBQZXJjZW50IiwNCiAgICBQb29sX1R5cGUgPT0gImRhbW1lZHBvb2xfcGVyY2VudCIgfiAiRGFtbWVkcG9vbCBQZXJjZW50Ig0KICApKQ0KDQojIENvbnZlcnQgcGVyY2VudGFnZXMgdG8gcHJvcG9ydGlvbnMgKDAgdG8gMSkNCnBsb3RfZGF0YV9sb25nX3BlcmNlbnQgPC0gcGxvdF9kYXRhX2xvbmdfcGVyY2VudCAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBQcm9wb3J0aW9uIC8gMTAwKQ0KDQojIERlZmluZSB0aGUgYmFzZSBmdWxsIHJlYWNoIChhbHdheXMgMSkgc2VwYXJhdGVseQ0KZnVsbF9yZWFjaCA8LSBwbG90X2RhdGFfbG9uZ19wZXJjZW50ICU+JQ0KICBmaWx0ZXIoUG9vbF9UeXBlID09ICJwb29sX3BlcmNlbnQiKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSAxKSAgIyBTZXQgdG8gZnVsbCByZWFjaA0KDQojIEZpbHRlciBvbmx5IHRoZSBzdGFja2VkIHByb3BvcnRpb25zDQpzdGFja2VkX3Bvb2xzIDwtIHBsb3RfZGF0YV9sb25nX3BlcmNlbnQgJT4lDQogIGZpbHRlcihQb29sX1R5cGUgJWluJSBjKCJzY291cnBvb2xfcGVyY2VudCIsICJkYW1tZWRwb29sX3BlcmNlbnQiKSkNCg0KIyBDcmVhdGUgdGhlIHBsb3QNCnN0YWNrZWRwbG90PC1nZ3Bsb3QoKSArDQogICMgRW1wdHkgZnVsbCBiYXIgb3V0bGluZSAoYWx3YXlzIGhlaWdodCAxKQ0KICBnZW9tX2JhcihkYXRhID0gZnVsbF9yZWFjaCwgYWVzKHggPSBmYWN0b3IoeWVhciksIHkgPSBQcm9wb3J0aW9uKSwNCiAgICAgICAgICAgc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSBOQSwgY29sb3IgPSAiYmxhY2siLCB3aWR0aCA9IDAuNykgKw0KICANCiAgIyBTdGFja2VkIGJhcnMgZm9yIHNjb3VycG9vbCAmIGRhbW1lZHBvb2wNCiAgZ2VvbV9iYXIoZGF0YSA9IHN0YWNrZWRfcG9vbHMsIGFlcyh4ID0gZmFjdG9yKHllYXIpLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IFBvb2xfVHlwZV9MYWJlbCksDQogICAgICAgICAgIHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuNykgKw0KICANCiAgIyBBZGQgcG9vbF9wZXJjZW50IGFzIGEgdGV4dCBsYWJlbCwgcG9zaXRpb25lZCBjb3JyZWN0bHkNCiAgZ2VvbV90ZXh0KGRhdGEgPSBwbG90X2RhdGFfbG9uZ19wZXJjZW50ICU+JSBmaWx0ZXIoUG9vbF9UeXBlID09ICJwb29sX3BlcmNlbnQiKSwNCiAgICAgICAgICAgIGFlcyh4ID0gZmFjdG9yKHllYXIpLCB5ID0gUHJvcG9ydGlvbiwgbGFiZWwgPSBzcHJpbnRmKCIlLjNmIiwgUHJvcG9ydGlvbikpLCANCiAgICAgICAgICAgIHNpemUgPSA0LCBmb250ZmFjZSA9ICJib2xkIiwgdmp1c3QgPSAtMC41KSArICAjIEFkanVzdCBwb3NpdGlvbiBzbGlnaHRseSBhYm92ZQ0KICANCiAgIyBGYWNldCBieSBTaXRlDQogIGZhY2V0X3dyYXAofiBTaXRlKSArDQogIA0KICAjIFNldCBmaWxsIGNvbG9ycyBhbmQgbGVnZW5kIHRleHQNCiAgc2NhbGVfZmlsbF9tYW51YWwoDQogICAgdmFsdWVzID0gYygiU2NvdXJwb29sIFBlcmNlbnQiID0gIiNGNEEyNjEiLCAiRGFtbWVkcG9vbCBQZXJjZW50IiA9ICIjMDA3MkIyIiksDQogICAgbGFiZWxzID0gYygiRGFtbWVkcG9vbCBQZXJjZW50IiA9ICJEYW1tZWQgUG9vbCIsIA0KICAgICAgICAgICAgICAgIlNjb3VycG9vbCBQZXJjZW50IiA9ICJTY291cmVkIFBvb2wiKSwNCiAgICBuYW1lID0gIlByb3BvcnRpb25hbCBjb21wb3NpdGlvbjoiDQogICkgKw0KICANCiAgIyBDdXN0b20gbGVnZW5kIGZvciBib2xkZWQgdGV4dA0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSA1KSksDQogICAgICAgICBzaGFwZSA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJCb2xkZWQgbnVtYmVyID0gdG90YWwgcG9vbCBwcm9wb3J0aW9uIiwgb3ZlcnJpZGUuYWVzID0gbGlzdChjb2xvciA9IE5BKSkpICsNCg0KICAjIExhYmVscyBhbmQgdGhlbWUNCiAgbGFicygNCiAgICB0aXRsZSA9ICJSZWFjaCBUaGFsd2VnIFByb3BvcnRpb24gYXMgUG9vbCBUeXBlIiwNCiAgICB4ID0gIlllYXIiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogIHlsaW0oMCwgMSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwNCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksDQogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKQ0KICApDQoNCkhVcGxvdHMNCnN0YWNrZWRwbG90DQojZXhwb3J0IGZpZ3VyZSBwZGYNCmV4cG9ydF9wbG90KHN0YWNrZWRwbG90LCAiUmVhY2ggVGhhbHdlZyBQcm9wb3J0aW9uIGFzIFBvb2wucGRmIikNCiNleHBvcnQgZmlndXJlIHBkZg0KZXhwb3J0X3Bsb3QoSFVwbG90cywgIlNoYW5ub24gSW5kZXggYW5kIFBvb2wtUmlmZmxlIFJhdGlvLnBkZiIpDQpgYGANCg0KDQoNCg==